sed или awk: удалить n строк по образцу


Как бы я смешал шаблоны и числовые диапазоны в sed (или любой подобный инструмент - awk например)? То, что я хочу сделать, это сопоставить определенные строки в файле и удалить следующие n строк перед продолжением, и я хочу сделать это как часть конвейера.

4 79

4 ответа:

Я попробую это сделать.

чтобы удалить 5 строк после шаблона (включая строку с шаблоном):

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

чтобы удалить 5 строк после шаблона (исключая строку с шаблоном):

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

простой awk решения:

предположим, что регулярное выражение для поиска совпадающих строк хранится в переменной оболочки $regex, и количество строк, чтобы пропустить в $count.

если соответствующие строки и пропустить ($count + 1 строки пропускаются):

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

если соответствующие строки не пропустить ($count строки после матч пропускаются):

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

объяснение:

  • -v regex="$regex" -v count="$count" определяет awk переменные на основе shell переменные с тем же именем.

Это решение позволяет передать "n" в качестве параметра, и он будет читать ваши шаблоны из файла:

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

файл с именем " - " означает stdin для awk, поэтому он подходит для вашего конвейера

Это может сработать для вас:

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