Pertanyaan sed atau awk: hapus n baris mengikuti pola


Bagaimana saya mencampur pola dan rentang numerik dalam sed (atau alat serupa - misalnya misalnya)? Yang ingin saya lakukan adalah mencocokkan baris-baris tertentu dalam sebuah file, dan menghapus baris-baris berikutnya sebelum melanjutkan, dan saya ingin melakukan itu sebagai bagian dari suatu saluran pipa.


75
2017-12-09 10:05


asal


Jawaban:


Saya akan mencobanya.

Untuk menghapus 5 baris setelah sebuah pola (termasuk garis dengan pola):

sed -e '/pattern/,+5d' file.txt

Untuk menghapus 5 baris setelah pola (tidak termasuk garis dengan pola):

sed -e '/pattern/{n;N;N;N;N;d}' file.txt

130
2017-12-09 12:56



Sederhana awk solusi:

Asumsikan bahwa ekspresi reguler yang digunakan untuk menemukan baris yang cocok disimpan dalam variabel shell $regex, dan jumlah baris untuk dilewati $count.

Jika itu baris yang cocok seharusnya juga dilewati ($count + 1 garis dilewati):

... | awk -v regex="$regex" -v count="$count" \
  '$0 ~ regex { skip=count; next } --skip >= 0 { next } 1'

Jika itu baris yang cocok seharusnya tidak dilewati ($count garis setelah pertandingan dilewati):

... | awk -v regex="$regex" -v count="$count" \
  '$0 ~ regex { skip=count; print; next } --skip >= 0 { next } 1'

Penjelasan:

  • -v regex="$regex" -v count="$count" mendefinisikan awk variabel berdasarkan kulit variabel dengan nama yang sama.
  • $0 ~ regex cocok dengan garis bunga
    • { skip=count; next } menginisialisasi jumlah lompatan dan melanjutkan ke baris berikutnya, secara efektif melewati garis yang sesuai; dalam solusi kedua, the print sebelum next memastikan itu tidak dilewati.
    • --skip >= 0 mengurangi hitungan lompatan dan mengambil tindakan jika (diam)> = 0, menyiratkan bahwa garis di tangan harus dilewati.
    • { next } hasil ke baris berikutnya, secara efektif melewati garis saat ini
  • 1 adalah singkatan yang umum digunakan untuk { print }; yaitu, garis saat ini hanya dicetak
    • Hanya baris yang tidak cocok dan tidak dilewati yang mencapai perintah ini.
    • Alasan itu 1 setara dengan { print } Apakah itu 1 Diartikan sebagai pola Boolean yang menurut definisi selalu bernilai true, yang berarti bahwa tindakan terkaitnya (blok) dieksekusi tanpa syarat. Karena ada tidak tindakan terkait dalam hal ini, awk default ke pencetakan garis.

4
2018-05-20 17:57



Solusi ini memungkinkan Anda melewatkan "n" sebagai parameter dan ia akan membaca pola Anda dari file:

awk -v n=5 '
    NR == FNR {pattern[$0]; next}
    {
        for (patt in pattern) {
            if ($0 ~ patt) {
                print # remove if you want to exclude a matched line
                for (i=0; i<n; i++) getline
                next
            }
        }
        print
    }
' file.with.patterns -

File bernama "-" berarti stdin untuk awk, jadi ini cocok untuk pipeline Anda


2
2017-12-09 15:17



Ini mungkin berhasil untuk Anda:

cat <<! >pattern_number.txt
> 5 3
> 10 1
> 15 5
> !
sed 's|\(\S*\) \(\S*\)|/\1/,+\2{//!d}|' pattern_number.txt |
sed -f - <(seq 21)
1 
2
3
4
5
9
10
12
13
14
15
21

2
2018-01-20 12:20