Использование sed для удаления всех строк между двумя соответствующими шаблонами - PullRequest
53 голосов
/ 09 июня 2011

У меня есть файл, похожий на:

# ID 1
blah blah
blah blah
$ description 1
blah blah
# ID 2
blah
$ description 2
blah blah
blah blah

Как я могу использовать команду sed для удаления всех строк между # и $ строкой?Таким образом, результатом будет:

# ID 1
$ description 1
blah blah
# ID 2
$ description 2
blah blah
blah blah

Не могли бы вы также дать объяснение?

Ответы [ 5 ]

47 голосов
/ 09 июня 2011

Используйте эту команду sed для достижения следующих целей:

sed '/^#/,/^\$/{/^#/!{/^\$/!d}}' file.txt

Пользователям Mac (для предотвращения ошибки extra characters at the end of d command) необходимо добавить точки с запятой перед закрывающими скобками

sed '/^#/,/^\$/{/^#/!{/^\$/!d;};}' file.txt

OUTPUT

# ID 1
$ description 1
blah blah
# ID 2
$ description 2
blah blah
blah blah

Объяснение:

  • /^#/,/^\$/ будет сопоставлять весь текст между строками, начинающимися с #, и строками, начинающимися с $.^ используется для начала символа строки.$ является специальным символом, поэтому его необходимо экранировать.
  • /^#/! означает выполнить следующее, если начало строки не равно #
  • /^$/! означает выполнить следующее, если начало строкине $
  • d означает удаление

Таким образом, в целом сначала выполняется сопоставление всех строк от ^# до ^\$, а затем из этих совпадающих строк находим строки, которые не совпадают ^# и не совпадают ^\$ и удаляются с помощью d.

33 голосов
/ 24 января 2013
$ cat test
1
start
2
end
3
$ sed -n '1,/start/p;/end/,$p' test
1
start
end
3
$ sed '/start/,/end/d' test
1
3
6 голосов
/ 26 сентября 2017

В общем случае, если у вас есть файл с содержимым формы abcde , где раздел a предшествует шаблону b , тогда раздел c предшествует шаблону d , затем следует раздел e , и после применения следующих команд sed вы получите следующие результаты.

В этой демонстрации выходные данные представлены => abcde, где буквы показывают, какие секции будут в выходных данных. Таким образом, ae показывает вывод только секций a и e , ace будет секциями a , c и е и т. Д.

Обратите внимание, что если b или d появятся в выходных данных, это те шаблоны, которые появляются (т.е. они обрабатываются так, как если бы они были разделами в выходных данных).

Также не путайте шаблон /d/ с командой d. Команда всегда в конце этих демонстраций. Шаблон всегда находится между //.

  • sed -n -e '/b/,/d/!p' abcde => ae
  • sed -n -e '/b/,/d/p' abcde => bcd
  • sed -n -e '/b/,/d/{//!p}' abcde => c
  • sed -n -e '/b/,/d/{//p}' abcde => бд
  • sed -e '/b/,/d/!d' abcde => bcd
  • sed -e '/b/,/d/d' abcde => ae
  • sed -e '/b/,/d/{//!d}' abcde => abde
  • sed -e '/b/,/d/{//d}' abcde => туз
5 голосов
/ 29 июня 2017

Другой подход с sed:

sed '/^#/,/^\$/{//!d;};' file
  • /^#/,/^\$/: от строки, начинающейся с # до следующей строки, начинающейся с $
  • //!d: удалить все строки, кроме тех, которые соответствуют шаблонам адресов
3 голосов
/ 09 июня 2011

Я сделал что-то подобное давным-давно, и это было что-то вроде:

sed -n -e "1,/# ID 1/ p" -e "/\$ description 1/,$ p"

Что-то вроде:

  • -n подавить все выходные данные
  • -e "1,/# ID 1/ p" выполнить с первой строки до вашего паттерна и p (print)
  • -e "/\$ description 1/,$ p" выполнить от второго шаблона до конца и p (печать).

Возможно, я ошибаюсь с некоторыми из экранирующих строк, поэтому, пожалуйста, перепроверьте.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...