Использование sed для удаления всех строк между двумя шаблонами соответствия
У меня есть файл вроде:
# 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
Не могли бы вы также дать объяснение?
Ответы
Ответ 1
Используйте эту команду 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
.
Ответ 2
$ 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
Ответ 3
Я сделал что-то вроде этого давным-давно, и это было что-то вроде:
sed -n -e "1,/# ID 1/ p" -e "/\$ description 1/,$ p"
Что-то вроде:
-
-n
подавляет весь вывод
-
-e "1,/# ID 1/ p"
выполнить из первой строки, пока ваш шаблон и p (печать)
-
-e "/\$ description 1/,$ p"
выполнить из второго шаблона до конца и p (печать).
Возможно, я ошибаюсь в некоторых экранах строк, поэтому, пожалуйста, дважды проверьте.
Ответ 4
Другой подход с sed:
sed '/^#/,/^\$/{//!d;};' file
-
/^#/,/^\$/
: от строки, начинающейся с #
, до следующей строки, начинающейся с $
-
//!d
: удалить все строки, кроме тех, которые соответствуют шаблонам адресов
Ответ 5
В общем виде, если у вас есть файл с содержимым формы abcde, где раздел a предшествует шаблону b, то раздел c предшествует шаблону d, затем следует раздел e, и вы применяете следующие команды sed
, вы получаете следующие результаты.
В этой демонстрации вывод представлен => abcde
, где буквы показывают, какие разделы будут на выходе. Таким образом, ae
показывает вывод только секций a и e, ace
будут сечениями a, c и e и т.д.
Обратите внимание, что если на выходе появляются 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
= > bd
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
= > ace