Saya memiliki file log yang sangat besar dan ingin memahami kemunculan pola yang pertama, dan kemudian menemukan pola lain tepat setelah kejadian ini.
Sebagai contoh:
123
XXY
214
ABC
182
558
ABC
856
ABC
Dalam contoh saya, saya ingin mencari 182
dan kemudian menemukan kejadian berikutnyaABC
Kejadian pertama sederhana:
grep -n -m1 "182" /var/log/file
Output ini:
5:182
Bagaimana saya menemukan kemunculan ABC selanjutnya?
Ide saya adalah memberitahu grep
untuk melewati n
baris pertama (dalam contoh di atas n=5
), berdasarkan nomor baris 182. Tetapi bagaimana saya melakukannya?
grep
digunakan? Saya tidak berpikir ini bisa dilakukan dengangrep
tetapi akan mudah denganawk
ataused
(sendiri atau dalam kombinasi dengangrep
).grep
tidak diperlukan. Saya belum begitu akrab dengansed
atauawk
. Jika Anda memiliki solusi yang baik, biarkan saya mendengarnya! :) @don_crissti hanya baris pertama yang harus dicetak. Saya tidak peduli dengan kejadian lainnya.Jawaban:
Dengan
sed
Anda dapat menggunakan rentang danq
masukan input pada satu penyelesaian:Demikian pula dengan GNU
grep
Anda dapat membagi input antara duagrep
s:... yang mencetak ...
... untuk menandakan bahwa yang pertama
grep
menemukan-F
string ixed-string literal,-x
seluruh baris 182 cocok 5 baris dari awal pembacaannya, dan yang kedua menemukan ABC match 2 baris yang sama dari awal readnya - atau 2 baris setelah yang pertamagrep
berhenti membaca di baris 5.Dari
man grep
:Saya menggunakan dokumen di sini demi demonstrasi yang dapat direproduksi, tetapi Anda mungkin harus melakukan:
Ini juga akan bekerja dengan konstruksi perintah majemuk shell lainnya seperti:
sumber
grep
's bukannya;
... no-gogrep
dibagikan kedua orang tersebut secara efektif merupakan saluran pipa untuk mereka. Sesuatu yang lain: Saya mencoba tanpa mencetak garis penanda tetapised '//,/^ABC$/!d;/^ABC$/!d;q'
melemparkan kesalahan yang aneh. Apa yang//
harus dilakukansed
hal itu - hanya menuliskannya dengan sangat cepat.sed
masalahnya bekerja - Anda baru saja meninggalkan referensi. Dised
Anda dapat merujuk yang terakhir/address/
lagi dengan//
alamat kosong . Begitu/^182$/command;//,/next_address/
juga/^182$/command;/^182$/,/next_address/
. Kesalahan Anda mungkin bukan ekspresi reguler sebelumnya jika Anda menggunakan GNUsed
. Ngomong-ngomong pipa lseek, omong-omong, dapat dimanipulasi melalui tipuan melalui/dev/fd/[num]
tautan pada sistem linux - tetapi jika Anda tidak terlalu berhati-hati untuk menangani buffer dengan baik (seperti dengandd
) itu biasanya pertempuran yang kalah.Gunakan
grep
dengan ekspresi reguler yang kompatibel dengan Perl (pcregrep
):Opsi
-M
memungkinkan pola untuk mencocokkan lebih dari satu baris, dan\K
tidak termasuk pola yang cocok (hingga titik ini) ke dalam output. Anda dapat menghapus\K
jika Anda ingin memiliki seluruh wilayah sebagai hasilnya.sumber
sumber
awk '/^182$/{z=1;next} z&&/^ABC$/{print NR":"$0;exit}' file
- atau Anda dapat menulis setidaknya satugetline()
loop eksplisit yang biasanya clumsier, atau menjadi pintar (?) menggunakan rentang yang hampir seperti @ JRFerguson perl:awk '!x&&/^182$/,/^ABC$/ {x=NR":"$0} END{print x}
Variasi Perl yang dapat Anda gunakan adalah:
... yang mencetak garis dalam kisaran yang cocok.
Jika file Anda berisi lebih dari satu rentang yang cocok, Anda dapat membatasi output hanya rentang pertama dengan mengubah
/
pembatas menjadi?
sumber
Tetap dengan adil
grep
dan menambahkantail
&cut
, Anda bisa ...grep untuk nomor baris dari kecocokan pertama
182
:Menggunakannya untuk grep untuk semua
ABC
's hanya setelah baris pencocokan pertama di atas, dengan menggunakantail
' s-n +K
untuk output setelah baris K'th. Bersama:Atau tambahkan
-m 1
lagi untuk menemukan hanya pencocokan pertamaABC
Referensi:
man
halaman/programming/6958841/use-grep-to-report-back-only-line-numbers
sumber
Varian lain adalah ini:
Bendera - Sebuah greps n baris setelah pertandingan dan 99999 hanya untuk memastikan kami tidak melewatkan apa pun. File yang lebih besar harus memiliki lebih banyak baris (tanyakan "wc -l").
sumber
Operator jangkauan
,
dapat digunakan di sini:Operator jangkauan
..
bersama-sama dengan operator yang hanya cocok satu kalim??
dapat digunakan di siniPerl
sumber