Вы можете сделать это с помощью awk
(gawk) без использования трубы.
$ awk -v RS='(^|\n)MARKER\n' 'END{printf "%s", $0}' file
jjj
kkk
lll
Пояснения:
- Вы определяете свою записьразделитель как
(^|\n)MARKER\n
через RS='(^|\n)MARKER\n'
, по умолчанию это EOL
char 'END{printf "%s", $0}'
=> в конце файла, вы печатаете всю строку, так как RS
установлен на(^|\n)MARKER\n
, $0
будет включать все строки до EOF.
Другой вариант - использовать
grep
(GNU):
$ grep -zoP '(?<=MARKER\n)(?:(?!MARKER)[^\0])+\Z' file
jjj
kkk
lll
Пояснения:
-z
для использования символа ASCII NUL в качестве разделителя -o
для печати только соответствующих -P
вактивировать режим Perl - Регулярное выражение PCRE:
(?<=MARKER\n)(?:(?!MARKER)[^\0])+\Z
объяснено здесь https://regex101.com/r/RpQBUV/2/
И последнее, но не менее важное: также может использоваться следующий подход
sed
:
sed -n '/^MARKER$/{n;h;b};H;${x;p}' file
jjj
kkk
lll
Пояснения:
n
перейти к следующей строке h
заменить пространство удержания текущей строкой H
сделать то же самое, но вместо замены,ppend ${x;p}
в конце обмена файлами (x
) удерживайте пробел и пробел и печатайте (p
)
, которые можно превратить в:
tac file | sed -n '/^MARKER$/q;p' | tac
, если мы используем tac
.