Удаление строк между 2 строками в Solaris

Я хочу удалить всю строку между двумя шаблонами, используя базовые awk или sed.

foo.txt :

 ---------------------------------------------------------------------- Cap in MB line 2 line 3 line 4 line 5 --------------------------------------------------- Cap in MB ---------------------------------------------------------------------- Cap in MB line 2 line 3 line 4 line 5 --------------------------------------------------- Cap in MB ---------------------------------------------------------------------- Cap in MB line 2 line 3 line 4 line 5 --------------------------------------------------- Cap in MB ---------------------------------------------------------------------- Cap in MB line 2 line 3 line 4 line 5 ---------------------------------------------------------------------- Cap in MB line 2 line 3 line 4 line 5 

output.txt :

 ---------------------------------------------------------------------- Cap in MB Deleted up to this point ---------------------------------------------------------------------- Cap in MB Deleted up to this point ---------------------------------------------------------------------- Cap in MB Deleted up to this point ---------------------------------------------------------------------- Cap in MB line 2 line 3 line 4 line 5 ---------------------------------------------------------------------- Cap in MB line 2 line 3 line 4 line 5 

Я использую solaris 5.10, базовый awk и sed. Количество строк между двумя шаблонами может изменяться. Обратите внимание, что вторая строка должна быть заменена, но не первая строка. Обратите внимание, что разница между двумя шаблонами – это количество тире. То, что вы видите в foo.txt – это именно то, что у меня есть в моем реальном файле.

  $ awk '!f{print} /----------------------/{f=!f;if (!f)print "Deleted up to this point"}' foo.txt ---------------------------------------------------------------------- Cap in MB Deleted up to this point ---------------------------------------------------------------------- Cap in MB Deleted up to this point ---------------------------------------------------------------------- Cap in MB Deleted up to this point 

Как это работает

Этот скрипт имеет одну переменную f . Когда f истинно (1), мы находимся в диапазоне строк, которые нужно удалить. Когда оно ложно (0), мы находимся в диапазоне, который должен быть напечатан.

По умолчанию f является ложным при запуске программы.

  • !f{print}

    Распечатайте любую строку, если f false.

  • /----------------------/{f=!f;if (!f)print "Deleted up to this point"}

    Если мы достигнем разделительной линии, отмеченной штрихами, инвертируем значение f . Если f теперь false, то напечатайте сообщение «deleted».

Обновить

По умолчанию awk для Solaris, похоже, имеет проблемы. Пытаться:

 nawk '!f{print} /----------------------/{f=!f;if (!f)print "Deleted up to this point"}' foo.txt 

Или,

 /usr/xpg4/bin/awk '!f{print} /----------------------/{f=!f;if (!f)print "Deleted up to this point"}' foo.txt 

Или,

 /usr/xpg6/bin/awk '!f{print} /----------------------/{f=!f;if (!f)print "Deleted up to this point"}' foo.txt 

Ответ на пересмотренный вопрос

 $ awk ' /^--------------------------------------------------- Cap in MB/{print "Deleted up to this point"; f=0; z=""; next;} /^---------------------------------------------------------------------- Cap in MB/{f=1; if(z)print substr(z,2); z=""; print;next;} f{z=z"\n"$0;next;} END{print substr(z,2);}' foo.txt ---------------------------------------------------------------------- Cap in MB Deleted up to this point ---------------------------------------------------------------------- Cap in MB Deleted up to this point ---------------------------------------------------------------------- Cap in MB Deleted up to this point ---------------------------------------------------------------------- Cap in MB line 2 line 3 line 4 line 5 ---------------------------------------------------------------------- Cap in MB line 2 line 3 line 4 line 5 

Вот простое решение с awk: выключите печать после длинной пунктирной линии, включите печать после короткой пунктирной линии.

 awk ' !do_not_print {print} $0 == "---------------------------------------------------------------------- Cap in MB" {do_not_print = 1} $0 == "--------------------------------------------------- Cap in MB" {do_not_print = 0} ' <foo.txt >output.txt 

Мой прием. Как и у John1024, но поскольку он находится в одной строке, он не читается.
Протестировано в окне Solaris 8.

 /usr/xpg4/bin/awk \ -v section_start='^---------------------------------------------------------------------- Cap in MB' \ -v delete_marker='^--------------------------------------------------- Cap in MB' \ ' $0 ~ section_start { for (i=1; i<=n; i++) print line[i] n=0 delete line print next } {line[++n] = $0} $0 ~ delete_marker { n=1 delete line line[1] = "Deleted up to this point" } END {for (i=1; i<=n; i++) print line[i]} ' foo.txt