Далее будет напечатана строка соответствия TERMINATE
до конца файла:
sed -n -e '/TERMINATE/,$p'
Объяснено: -n
отключает поведение по умолчанию sed
при печати каждой строки после выполнения сценария на нем, -e
указывает сценарий на sed
, /TERMINATE/,$
это выбор диапазона адресов (строк), означающий, что первая строка соответствует TERMINATE
регулярному выражению (например, grep) до конца файла ( $
) и p
- команда печати, которая печатает текущую строку.
Это напечатает от строки, которая следует за соответствующей строкой TERMINATE
до конца файла:
(от ПОСЛЕ соответствующей строки к EOF, НЕ включая соответствующую строку)
sed -e '1,/TERMINATE/d'
Объяснено: 1,/TERMINATE/
это выбор диапазона адресов (строк), означающий первую строку для ввода в 1-ю строку, соответствующую TERMINATE
регулярному выражению, и d
это команда удаления, которая удаляет текущую строку и переходит к следующей строке. Так как по sed
умолчанию выполняется печать строк, он будет печатать строки после TERMINATE
конца ввода.
Редактировать:
Если вы хотите строки раньше TERMINATE
:
sed -e '/TERMINATE/,$d'
И если вы хотите обе строки до и после TERMINATE
в 2 разных файлах за один проход:
sed -e '1,/TERMINATE/w before
/TERMINATE/,$w after' file
Файлы before и after будут содержать строку с terminate, поэтому для обработки каждого из них вам необходимо использовать:
head -n -1 before
tail -n +2 after
Edit2:
Если вы не хотите жестко кодировать имена файлов в сценарии sed, вы можете:
before=before.txt
after=after.txt
sed -e "1,/TERMINATE/w $before
/TERMINATE/,\$w $after" file
Но тогда вы должны избежать $
значения последней строки, чтобы оболочка не пыталась расширить $w
переменную (обратите внимание, что теперь мы используем двойные кавычки вокруг сценария вместо одинарных кавычек).
Я забыл сказать, что новая строка важна после имен файлов в скрипте, так что sed знает, что имена файлов заканчиваются.
Изменить: 2016-0530
Себастьян Клеман спросил: «Как бы вы заменили жестко закодированную TERMINATE
переменную?»
Вы должны сделать переменную для соответствующего текста, а затем сделать это так же, как в предыдущем примере:
matchtext=TERMINATE
before=before.txt
after=after.txt
sed -e "1,/$matchtext/w $before
/$matchtext/,\$w $after" file
использовать переменную для сопоставления текста с предыдущими примерами:
## Print the line containing the matching text, till the end of the file:
## (from the matching line to EOF, including the matching line)
matchtext=TERMINATE
sed -n -e "/$matchtext/,\$p"
## Print from the line that follows the line containing the
## matching text, till the end of the file:
## (from AFTER the matching line to EOF, NOT including the matching line)
matchtext=TERMINATE
sed -e "1,/$matchtext/d"
## Print all the lines before the line containing the matching text:
## (from line-1 to BEFORE the matching line, NOT including the matching line)
matchtext=TERMINATE
sed -e "/$matchtext/,\$d"
Важными моментами о замене текста переменными в этих случаях являются:
- Переменные (
$variablename
), заключенные в single quotes
[ '
], не будут «расширяться», но переменные внутри double quotes
[ "
] будут. Таким образом, вы должны изменить все , single quotes
чтобы , double quotes
если они содержат текст , который вы хотите заменить переменную.
- В
sed
диапазонах также содержат $
и сразу же следуют буква , как: $p
, $d
, $w
. Они также будут выглядеть как переменные , которые будут расширены, так что вы должны избежать этих $
символов с обратной косой черты [ \
] , как: \$p
, \$d
, \$w
.
grep 'TERMINATE' file