Следующая строка напечатает строку, соответствующую TERMINATE
до конца файла:
sed -n -e '/TERMINATE/,$p'
Объяснено: -n
отключает поведение по умолчанию sed
печати каждой строки после выполнения на ней своего сценария, -e
указывает сценарий на sed
, /TERMINATE/,$
является адресом ( line) выбор диапазона означает, что первая строка соответствует регулярному выражению TERMINATE
(например, grep) и концу файла ($
), а p
- команда печати, которая печатает текущую строку.
Будет выведено из строки, следующей за строкой, соответствующей TERMINATE
, до конца файла:
(от ПОСЛЕ совпадающей строки до EOF, НЕ включая совпадающую строку)
sed -e '1,/TERMINATE/d'
Объяснено: 1,/TERMINATE/
- выбор диапазона адресов (строк), означающий, что первая строка для ввода в 1-ю строку соответствует регулярному выражению TERMINATE
, а d
- команда удаления, которая удалить текущую строку и перейти к следующей строке. Так как sed
поведение по умолчанию - печать строк, он будет печатать строки после TERMINATE
до конца ввода.
Edit:
Если вы хотите строки до TERMINATE
:
sed -e '/TERMINATE/,$d'
А если вам нужны обе строки до и после TERMINATE
в 2 разных файлах за один проход:
sed -e '1,/TERMINATE/w before
/TERMINATE/,$w after' file
В файлах до и после будет строка с завершением, поэтому для обработки каждого из них вам необходимо использовать:
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
.