grep file, tetapi tampilkan beberapa baris di sekitarnya?

3420

Saya ingin grepstring, tetapi juga menunjukkan lima baris sebelumnya dan lima baris berikut serta garis yang cocok. Bagaimana saya bisa melakukan ini?

Mark Harrison
sumber
3
Saya menyimpan salinan skrip perl Brendan Gregg untuk tujuan ini. Bekerja dengan baik.
Ethan Post
6
Untuk solusi yang berfungsi pada Solaris, lihat tautan ini .
jahroy
107
man grep | grep -C 1 context:)
StvnW
20
man grep | grep -C 1 "\-C";)
Anders B
9
@StvnW ... Saya tidak tahu apakah akan memanggil meta itu (dalam konteks yang lebih umum, bukan SO), atau apa yang harus disebut. Anda menjawab pertanyaan dengan menunjukkan cara menggunakan jawaban untuk menemukan jawabannya.
bballdave025

Jawaban:

4539

Untuk BSD atau GNU grep Anda dapat menggunakan -B numuntuk mengatur berapa baris sebelum pertandingan dan -A numuntuk jumlah baris setelah pertandingan.

grep -B 3 -A 2 foo README.txt

Jika Anda ingin jumlah baris yang sama sebelum dan sesudah Anda dapat menggunakan -C num.

grep -C 3 foo README.txt

Ini akan menampilkan 3 baris sebelum dan 3 baris setelah.

Pat Notz
sumber
56
Itu bagus tapi sayangnya grep Solaris tidak mendukung itu. Lihat tautan itu untuk solaris: unix.com/solaris/33533-grep-display-few-lines-before-after.html
рüффп
9
Ok, tapi bagaimana jika ingin menunjukkan semua lini output setelah pertandingan? grep -A0 dan grep -A-1 jangan memotongnya ...
g33kz0r
2
tidak bekerja untuk saya karena beberapa alasan, meskipun disebutkan di halaman manual saya.
Hayri Uğur Koltuk
2
Jika Anda adalah HP-UX env, tidak ada versi grep yang berfungsi seperti di Solaris. Mampu menggunakan tautan Solaris tetapi mengganti nawk dengan awk di tautan itu.
zkarthik
6
-n adalah untuk nomor baris, tetapi untuk beberapa versi grep -n # akan menampilkan # garis di sekitarnya (seperti -c) dengan nomor baris. Itu jalan pintas yang bermanfaat dan tujuan saya ketika saya membutuhkan konteks.
Anthony DiSanti
607

-Adan -Bakan bekerja, seperti yang akan -C n(untuk ngaris konteks), atau adil -n(untuk ngaris konteks ... selama n adalah 1 hingga 9).

Stu
sumber
Saya mencoba -nformat dan ternyata hanya berfungsi sampai 9. Untuk 15itu mengembalikan 5 baris
Deepak Mahakale
8
@DeepakMahakale Ini mungkin terkait dengan bagaimana argumen / opsi baris perintah biasanya diurai oleh program POSIX. Penentu opsi adalah karakter tunggal (seperti -A, -Batau -C). Biasanya, specifier opsi diikuti oleh nilai ( -o a.outuntuk menentukan file output di GCC), tetapi juga dapat berfungsi sebagai saklar / bendera sederhana ( -guntuk mengaktifkan info debug di GCC). Namun spasi di antara opsi bersifat opsional, jadi untuk opsi tanpa nilai, dimungkinkan untuk menggabungkannya ( -ABC), yang berarti -15ditafsirkan -1 -5(dua opsi terpisah) dan -5mengabaikannya -1.
natiiix
1
-5 lebih cepat dari keduanya -A 5 -B 5. Itu tidak dimaksudkan untuk digunakan bersama. Lebih bersih untuk pembaca skrip lain jika Anda memilih -A atau -B atau -C lebih dari -9.
Eric Aldinger
77

ack bekerja dengan argumen yang sama dengan grep, dan accept -C. Tetapi biasanya lebih baik untuk mencari melalui kode.

elmarco
sumber
5
ACK juga mendukung -A -B.
Shuo
Ack lebih baik daripada grep dalam banyak hal. Lebih cepat dengan sintaksis yang lebih sederhana.
chim
1
grep memiliki kelebihan karena diinstal secara default pada banyak sistem.
Marc Z
1
@MarcZ: Benar, grep lebih cenderung diinstal secara default daripada ack, tetapi ack adalah skrip yang portabel dan berdiri sendiri. Tidak perlu mengkompilasinya atau menginstalnya di direktori sistem seperti / usr / bin /. Setelah diunduh dan ditempatkan ke direktori yang terdaftar di $ PATH (dan set bit izin eXecute-nya), itu akan langsung berfungsi. (Tidak ada sudo atau hak akses root yang diperlukan untuk mendapatkan ack untuk bekerja.)
JL
Pertanyaan ini tentang grep, tidak yakin menggunakannya untuk "beriklan" ack(yang merupakan alat yang hebat, memang) adalah ide yang bagus ...
MonsieurDart
39
grep astring myfile -A 5 -B 5

Itu akan menangkap "myfile" untuk "astring", dan menunjukkan 5 baris sebelum dan sesudah setiap pertandingan

dbr
sumber
19
"grep astring myfile -C 5" akan melakukan hal yang sama
Syed Siraj Uddin
20

Saya biasanya menggunakan

grep searchstring file -C n # n for number of lines of context up and down

Banyak alat seperti grep juga memiliki file man yang sangat hebat. Saya menemukan diri saya banyak merujuk ke halaman manual grep karena ada banyak hal yang dapat Anda lakukan dengannya.

man grep

Banyak alat GNU juga memiliki halaman info yang mungkin memiliki informasi yang lebih berguna selain halaman manual.

info grep
Sam Merrell
sumber
13

Gunakan grep

$ grep --help | grep -i context
Context control:
  -B, --before-context=NUM  print NUM lines of leading context
  -A, --after-context=NUM   print NUM lines of trailing context
  -C, --context=NUM         print NUM lines of output context
  -NUM                      same as --context=NUM
Chiel ten Brinke
sumber
Apakah Anda tidak membaca jawaban yang diterima? Anda hanya mengulangi apa yang sudah dikatakan pada pertanyaan yang berusia hampir 10 tahun ...
Yokai
7
Oh maafkan aku Yokai. Tetapi saya tidak membaca apa pun tentang memahami bagian bantuan grep untuk mendapatkan jawabannya.
Chiel ten Brinke
1
@Yokai Selain apa yang dikatakan Chiel ten Brinke, jawaban yang diterima tidak menyebutkan opsi panjang
user3738870
11

Cari "17655" di "/some/file.txt" menampilkan 10 baris konteks sebelum dan sesudah (menggunakan Awk), output diawali dengan nomor baris diikuti oleh titik dua. Gunakan ini pada Solaris ketika 'grep' tidak mendukung opsi "- [ACB]".

awk '

/17655/ {
        for (i = (b + 1) % 10; i != b; i = (i + 1) % 10) {
                print before[i]
        }
        print (NR ":" ($0))
        a = 10
}

a-- > 0 {
        print (NR ":" ($0))
}

{
        before[b] = (NR ":" ($0))
        b = (b + 1) % 10
}' /some/file.txt;
Malcolm Boekhoff
sumber
7

ripgrep

Jika Anda peduli dengan kinerja, gunakan ripgrepsintaksis yang mirip dengan grep, misalnya

rg -C5 "pattern" .

-C, --context NUM- Tampilkan NUM baris sebelum dan sesudah setiap pertandingan.

Ada juga parameter seperti -A/ --after-contextdan -B/ --before-context.

Alat ini dibangun di atas mesin regex Rust yang membuatnya sangat efisien pada data besar.

kenorb
sumber
5

Ini adalah solusi @ Tech diawk

awk 'c-->0;$0~s{if(b)for(c=b+1;c>1;c--)print r[(NR-c+1)%b];print;c=a}b{r[NR%b]=$0}' b=3 a=3 s="pattern" myfile

Catatan: Ganti adan bvariabel dengan jumlah baris sebelum dan sesudah.

Ini sangat berguna untuk sistem yang tidak mendukung parameter grep -A, -Bdan -C.

kenorb
sumber
4
$ grep thestring thefile -5

-5membuat Anda 5baris di atas dan di bawah pertandingan 'thestring' setara dengan -C 5atau -A 5 -B 5.

JBone
sumber
4

Grep memiliki opsi bernama Context Line Control, Anda dapat menggunakan --contextdi dalamnya, cukup,

| grep -C 5

atau

| grep -5

Sebaiknya lakukan triknya

utama
sumber
1

Saya gunakan untuk melakukan cara yang kompak

grep -5 string file

Itu setara dengan

grep -A 5 -B 5 string file
Franzisk
sumber
0

Jika Anda sering mencari kode, AG pencari perak jauh lebih efisien (lebih cepat) daripada grep.

Anda menunjukkan garis konteks dengan menggunakan opsi -C.

Misalnya:

ag -C 3 "foo" myFile

line 1
line 2
line 3
line that has "foo"
line 5
line 6
line 7
Mawar
sumber