Используя awk
или sed
как я могу выбрать линии, которые встречаются между двумя разными шаблонами маркеров? Эти шаблоны могут быть отмечены несколькими разделами.
Например: предположим, что файл содержит:
abc
def1
ghi1
jkl1
mno
abc
def2
ghi2
jkl2
mno
pqr
stu
И начальный образец, abc
а конечный образец - mno
Итак, мне нужен вывод как:
def1
ghi1
jkl1
def2
ghi2
jkl2
Я использую sed, чтобы один раз сопоставить шаблон:
sed -e '1,/abc/d' -e '/mno/,$d' <FILE>
Есть ли способ sed
или awk
не делать это несколько раз до конца файла?
awk '/abc/{a=1}/mno/{print;a=0}a' file
.awk '/abc/{a=1} a; /mno/{a=0}' file
- с этим, поставивa
условие перед,/mno/
мы заставим его оценить строку как истинную (и распечатать ее) перед установкойa=0
. Таким образом мы можем избежать написанияprint
.awk '/abc/,/mno/' file
awk '/abc/{flag=1}/mno/{flag=0}flag' file
должен сделать.awk 'flag; /PAT1/{flag=1; next} /PAT1/{flag=0}' file
сделал бы.Использование
sed
:Параметр
-n
означает, что по умолчанию не печатать.Шаблон ищет строки, содержащие только
abc
одноmno
, а затем выполняет действия в{ ... }
. Первое действие удаляетabc
строку; втораяmno
линия; иp
печатает оставшиеся строки. При необходимости вы можете расслабить регулярные выражения. Строки вне диапазонаabc
..mno
просто не печатаются.источник
-e
sed
должен выполняться. Если вы хотите или должны использовать несколько аргументов для включения всего сценария, вы должны использовать их-e
перед каждым таким аргументом; в противном случае это необязательно (но явно).d
ко всем строкам до первого совпадения, а затем ещеd
ко всем строкам, начиная со второго совпадения?Это может сработать для вас (GNU sed):
Удалите все строки, кроме строк между началом
abc
иmno
источник
!d;//d
гольф на 2 персонажа лучше :-) stackoverflow.com/a/31380266/895245{//!b}
препятствует тому , чтобыabc
иmno
от включения в выходной, но я не могу понять, каким образом . Могли бы вы объяснить?//!b
читает, если текущая строка не является ни одной из строк, соответствующих диапазону, прервать и, следовательно, распечатать эти строки, иначе все остальные строки будут удалены.играет в гольф на двух персонажей лучше, чем у ppotong
{//!b};d
Пустые косые черты
//
означают: «повторно использовать последнее использованное регулярное выражение». и команда делает то же самое, что и более понятное:Это , как представляется, POSIX :
источник
Судя по ссылкам, приведенным в предыдущем ответе, я сделал это за меня, работая
ksh
на Solaris, следующим образом:1,/firstmatch/d
: со строки 1 до первого поискаfirstmatch
, удалите./secondmatch/,$d
: удалить с первого появленияsecondmatch
до конца файла.источник
1,
) стоит раньше/firstmatch/
? Полагаю, это тоже можно сформулировать'/firstmatch/1,d;/secondmatch,$d'
?источник
что-то вроде этого работает для меня:
file.awk:
используя:
awk -f file.awk data
...edit: решение O_o fedorqui намного лучше / красивее, чем мое.
источник
if (record=1)
должен бытьif (record==1)
, то есть двойным=
- см. Операторы сравнения gawkОтвет Don_crissti от Показать только текст между двумя совпадающими шаблонами ?
что намного эффективнее, чем приложение AWK, см. здесь .
источник
Я пытался использовать
awk
для печати строк между двумя шаблонами, в то время как шаблон2 также соответствует шаблону1 . И строка pattern1 также должна быть напечатана.например, источник
должен иметь выход
Где
package BBB
шаблон1, шаблон2package \w*
. Обратите внимание, чтоCCC
это неизвестное значение, поэтому не может быть сопоставлено буквально.В этом случае у меня не работают ни @scai,
awk '/abc/{a=1}/mno/{print;a=0}a' file
ни @fedorquiawk '/abc/{a=1} a; /mno/{a=0}' file
.Наконец, мне удалось решить эту проблему
awk '/package BBB/{flag=1;print;next}/package \w*/{flag=0}flag' file
, ха-хаНемного больше усилий приведет к тому
awk '/package BBB/{flag=1;print;next}flag;/package \w*/{flag=0}' file
, чтобы напечатать также строку pattern2, то естьисточник