Saya menggunakan ini
cat foo.txt | sed '/bar/d'
untuk menghapus baris yang berisi string bar
dalam file.
Namun saya ingin menghapus garis-garis dan garis langsung setelahnya . Lebih disukai di sed
, awk
atau alat lain yang tersedia di MinGW32.
Ini semacam kebalikan dari apa yang aku bisa di grep
dengan -A
dan -B
untuk mencetak garis pencocokan serta jalur sebelum / setelah baris cocok.
Apakah ada cara mudah untuk mencapainya?
text-processing
sed
awk
replace
jakub.g
sumber
sumber
Jawaban:
Jika Anda memiliki GNU sed (Linux atau Cygwin yang tidak tertanam):
Jika Anda memiliki
bar
dua baris berturut-turut, ini akan menghapus baris kedua tanpa menganalisisnya. Misalnya, jika Anda memiliki file 3-linebar
/bar
/foo
, yangfoo
garis akan tinggal.sumber
bar
sehingga yang ini sangat mudah diingat.sed '/bar/d'
jika Anda hanya ingin "Hapus baris yang berisi string tertentu" dan bukan yang berikutnya.sed '/math/q'
sed '/bar/d'
Jika
bar
dapat terjadi pada baris yang berurutan, Anda dapat melakukan:yang dapat diadaptasi untuk menghapus lebih dari 2 baris dengan mengubah 2 di atas dengan jumlah baris yang akan dihapus termasuk yang cocok.
Jika tidak, itu mudah dilakukan
sed
dengan solusi @MichaelRollins atau:sumber
/bar/
dengan/bar|baz|whatever/
. Dalamsed
sintaks itu sepertinya tidak berfungsi.sed
untuk menggunakan ekspresi reguler "extended". Informasi lebih lanjut di sini: gnu.org/software/sed/manual/html_node/… . Harap dicatat bahwa ini juga berlaku untukgrep
. Berikut contoh kerja saya sendiri:echo $'0a\n1b\n2c' | sed '/0a\|1b/d'
.Saya tidak lancar dalam sed, tetapi mudah untuk melakukannya dalam awk:
Script awk berbunyi: untuk baris yang berisi bar, dapatkan baris berikutnya (getline), lalu lewati semua pemrosesan selanjutnya (selanjutnya). Pola 1 di ujung mencetak garis yang tersisa.
Memperbarui
Seperti yang ditunjukkan dalam komentar, solusi di atas tidak bekerja secara berurutan
bar
. Berikut adalah solusi yang telah direvisi, yang mempertimbangkannya:Kami sekarang terus membaca untuk melewati semua / bar / baris.
sumber
grep -A
100%, Anda juga perlu menangani sejumlahbar
garis berturut-turut dengan benar (dengan menghapus seluruh blok dan 1 baris setelahnya).Anda akan ingin memanfaatkan kemampuan skrip sed untuk mencapai ini.
Contoh data:
Perintah "N" menambahkan baris input berikutnya ke dalam ruang pola. Ini dikombinasikan dengan garis dari pencocokan pola (/ bar /) akan menjadi garis yang ingin Anda hapus. Anda kemudian dapat menghapus secara normal dengan perintah "d".
sumber
sed -e '/bar/{N;d}' sample1.txt
Jika ada garis segera setelah pertandingan harus dihapus maka
sed
program Anda harus mempertimbangkan pertandingan berturut-turut. Dengan kata lain, jika Anda menghapus garis mengikuti pertandingan yang juga cocok, maka mungkin Anda harus menghapus garis yang mengikuti itu juga.Ini diterapkan cukup sederhana - tetapi Anda harus melihat ke belakang sedikit.
Ini bekerja dengan menukar ruang pegang dan pola untuk setiap baris yang dibaca - sehingga baris terakhir dapat dibandingkan dengan saat ini setiap kali. Jadi ketika
sed
membaca sebuah baris, ia bertukar konten buffer-nya - dan baris sebelumnya kemudian isi dari buffer editnya, sedangkan baris saat ini diletakkan di ruang penyimpanan.Jadi,
sed
periksa baris sebelumnya untuk kecocokanmatch
, dan jika!
tidak ditemukan dua ekspresi dalam{
fungsi}
dijalankan.sed
akang
et pegangan ruang dengan Timpa ruang pola - yang berarti baris saat kemudian di kedua ditahan dan pola ruang - dan kemudian akan//
memeriksa untuk pertandingan ke ekspresi reguler yang paling baru-baru ini disusun -match
- dan jika itu tidakmatch
itu adalahp
rinted.Ini berarti suatu garis hanya dicetak jika tidak dan garis sebelumnya tidak . Ini juga membatalkan pertukaran yang tidak perlu untuk urutan es.
match
match
match
Jika Anda menginginkan versi yang dapat menjatuhkan jumlah baris sewenang-wenang yang terjadi setelahnya,
match
itu akan membutuhkan sedikit lebih banyak pekerjaan:... ganti 5 dengan jumlah garis (termasuk garis yang cocok) yang ingin Anda hapus ...
sumber