Di bawah ini adalah teks dalam file:
Pseudo name=Apple
Code=42B
state=fault
Pseudo name=Prance
Code=43B
state=good
Saya perlu grep untuk "42B" dan mendapatkan output dari teks di atas seperti:
Pseudo name=Apple
Code=42B
state=fault
Adakah yang punya ide tentang cara mencapai ini menggunakan grep
/ awk
/ sed
?
Jawaban:
Dengan
awk
RS=
mengubah pemisah rekaman input dari baris baru ke baris kosong. Jika ada bidang dalam catatan yang berisi/42B/
cetak catatan.''
(string nol) adalah nilai ajaib yang digunakan untuk mewakili baris kosong menurut POSIX :Paragraf keluaran tidak akan dipisahkan karena pemisah keluaran tetap menjadi satu baris baru. Untuk memastikan bahwa ada garis kosong antara paragraf output, atur pemisah catatan output ke dua baris baru:
sumber
FILENAME
), itu bukan ide yang buruk untuk menggunakan pengalihan karena menghindari masalah untuk nama file yang mengandung=
atau dimulai dengan-
(atau sedang-
), membuat pesan kesalahan yang konsisten, dan menghindari menjalankanawk
atau melakukan pengalihan lainnya jika file input tidak dapat dibuka.Dengan asumsi data terstruktur sehingga selalu menjadi baris sebelum dan sesudah yang Anda inginkan, Anda dapat menggunakan sakelar grep
-A
(setelah) dan-B
(sebelum) untuk mengatakannya menyertakan 1 baris sebelum pertandingan dan 1 baris setelahnya:Jika Anda menginginkan garis angka yang sama sebelum dan sesudah istilah pencarian, Anda dapat menggunakan
-C
sakelar (konteks):Jika Anda ingin menjadi lebih ketat ketika mencocokkan beberapa baris, Anda dapat menggunakan alat ini
pcregrep
, untuk mencocokkan pola pada beberapa baris:Pola di atas cocok sebagai berikut:
-M
- beberapa baris'Pseudo.*\n.*42B.*\nstate.*'
- cocok dengan sekelompok string di mana string pertama dimulai dengan kata yang"Pseudo"
diikuti oleh karakter apa pun hingga akhir baris\n
, diikuti oleh karakter apa saja hingga string"42B"
diikuti oleh karakter apa pun hingga akhir baris (\n
), diikuti oleh string"state"
diikuti oleh karakter apa saja.sumber
-C
(konteks) dapat digunakan sebagai jalan pintas, jika-A
dan-B
sama.Mungkin ada cara yang sama mudahnya untuk melakukannya dengan awk, tetapi dalam perl:
Yang pada dasarnya mengatakan untuk membagi file menjadi potongan-potongan yang dibatasi oleh baris kosong, kemudian hanya mencetak potongan-potongan yang cocok dengan ekspresi reguler Anda.
sumber
cat
- sia dari ;perl -00 -ne 'print if /42B/' file
The
grep
beberapa rasa Unix memiliki-p
bendera untuk "ayat". Saya tahu AIX tidak .akan melakukan apa yang Anda minta di sana. YMMV dan GNU grep tidak memiliki flag ini.
sumber
Solusi perl lainnya, tanpa garis kosong tertinggal:
Contoh
sumber
perl -00 -ne 'print if /42B/' file
.