Saya mem-parsing file kotak surat yang menyimpan laporan server email untuk email yang gagal terkirim. Saya ingin mengekstrak alamat email yang salah, sehingga saya menghapusnya dari sistem. File log terlihat seperti ini:
...some content...
The mail system
<[email protected]>: host mx1.hotmail.com[65.54.188.94] said: 550
Requested action not taken: mailbox unavailable (in reply to RCPT TO
command)
...some content...
The mail system
<[email protected]>: host viking.optimumpro.net[79.101.51.82] said: 550
Unknown user (in reply to RCPT TO command)
...some content...
The mail system
<[email protected]>: host mta5.am0.yahoodns.net[74.6.140.64] said: 554
delivery error: dd This user doesn't have a yahoo.com account
([email protected]) [0] - mta1172.mail.sk1.yahoo.com (in reply to end
of DATA command)
...etc.
Alamat surel datang 2 baris setelah satu baris dengan "Sistem surat". Menggunakan grep seperti ini memberi saya baris "Sistem surat" dan dua baris berikutnya:
grep -A 2 "The mail system" mbox_file
Namun, saya tidak tahu cara menghapus baris "Sistem surat" dan baris kosong kedua dari keluaran ini. Saya kira saya bisa menulis skrip PHP / Perl / Python untuk melakukannya, tapi saya ingin tahu apakah ini mungkin dengan grep atau alat standar lainnya. Saya mencoba memberikan offset negatif ke parameter -B:
grep -A 2 -B -2 "The mail system" mbox_file
Tapi grep mengeluh:
grep: -2: invalid context length argument
Apakah ada cara untuk melakukan ini dengan grep?
Jawaban:
Cara paling sederhana untuk menyelesaikannya
grep
hanya menggunakan , adalah untuk pipa satu lagi terbalikgrep
di akhir. Sebagai contoh:sumber
Jika Anda tidak dikunci untuk menggunakan
grep
, cobased
...Ketika ia menemukan baris yang berisi "Sistem surat", ia membaca baris berikutnya dua kali, melalui
n;n;
, membuang setiap baris sebelumnya saat melakukannya.Ini meninggalkan baris ke-3 grup Anda dalam ruang pola, yang kemudian dicetak melalui
p
perintah sed .-n
Opsi utama mencegah semua pencetakan lainnya.Untuk mencetak dua baris berikutnya juga, itu hanya kasus berikutnya dan mencetak
n;p
dua kali lagi.Baris berikutnya membaca untuk baris yang Anda butuhkan dapat diakumulasikan dan dicetak satu blok dengan hanya satu
p
...N
membaca baris berikutnya dan menambahkannya ke ruang pola,Ini adalah versi kental terakhir ...
Jika Anda ingin seperator kelompok , mirip dengan keluaran wouuld apa yang grep, Anda dapat menggunakan sed ini menyisipkan perintah
i
(yang harus perintah terakhir pada baris) ...Berikut ini sintaks untuk menyertakan seperator grup
Ini adalah output untuk pertandingan pertama:
sumber
-B
untuk baris sebelumnya, jadi tidak perlu memberikan nilai -negatif.sumber
-A 2 -B 2
mencetak dari dua baris sebelum konteks menjadi 2 baris setelah konteks. Pertanyaannya adalah tentang mencetak dari 2 baris setelah konteks menjadi 4 baris setelah konteks.Saya tidak melihat gunanya hanya menggunakan grep, kecuali jika itu merupakan kendala yang ketat. Itu tidak dapat dilakukan dengan satu panggilan ke grep.
sumber
Ini mencetak 1 baris berikutnya setelah pertandingan regexp, menggunakan Perl
sumber