awk или sed строки между одинаковыми шаблонами, включая первое совпадение

Это текст:

* Tue This is the first line

– info 1

– info 2

– info 3

* Wed This is not to be included

Вывод этого текста должен быть таким:

* Tue This is the first line

– info 1

– info 2

– info 3

ПРИМЕЧАНИЕ: Я пробовал awk и sed, но не смог найти свой вывод. Проблема в том, что START и END - это одинаковые '*' (звездочка), и первый из них должен быть включен в вывод.

0
14.03.2017, 14:09
3 ответа

Сохраните образец текста в переменной:

$ SAMPLE=$(cat <<EOF
* Tue This is the first line

– info 1

– info 2

– info 3

* Wed This is not to be included
* Tue This is the first line

– info 1

– info 2

– info 3

* Wed This is not to be included
EOF
)

Используйте awk , чтобы обработать $ SAMPLE :

$ awk '{if($1~"\*"){if(p==1){p=0;next}else{p=1}}if(p==1){print $0}}' <<<"$SAMPLE"
* Tue This is the first line

– info 1

– info 2

– info 3

* Tue This is the first line

– info 1

– info 2

– info 3

РЕДАКТИРОВАТЬ

Как было предложено в комментариях, существует удивительно элегантное решение awk :

$ awk '/^\*/{p=!p};p' <<<"$SAMPLE"
* Tue This is the first line

– info 1

– info 2

– info 3

* Tue This is the first line

– info 1

– info 2

– info 3

Как это работает:

  • / ^ \ * / {p =! P}; - это будет измените значение p на 1 и 0 . Он станет 1 при первом обнаружении регулярного выражения / ^ \ * / . При втором обнаружении p станет 0 и так далее.

  • p - это эквивалент p {print} . Поскольку print является действием по умолчанию в awk , оно всегда будет печатать, когда предварительное условие оценивается как значение true , в данном случае, когда p становится 1 .

0
28.01.2020, 04:47

Надеюсь, я правильно понимаю. Этот сценарий удалит все из строки, начиная со второго * до конца буфера, создав желаемый результат из примера:

sed -n 'H;1h;$x;$s/\(\*[^*]*\)\n\*.*$/\1/p'

Пояснение добавить все строки ( H ) в буфер удержания. Для удержания последнего обмена строкой и буфера шаблонов ( $ x ), поэтому у вас есть весь файл как один шаблон. В этом шаблоне сохраняемая часть устанавливается в \ (\) и сохраняется ( \ 1 ), в то время как все, начиная с новой строки с * , удаляется.

Это соответствует вашему описанию, но если это не подходит для всех возможных примеров, вы можете изменить сценарий.

0
28.01.2020, 04:47
perl -lne 'if ( m?^\*? ... m?^\*? ) { print if !// || !$a++ }'

sed -e '
   /^\*/!d
   :loop
       $q; N
   /\n\*/!bloop
   s/\(.*\)\n.*/\1/;q
'

sed -e '
   /^\*/!d
   :loop
      n
   //!bloop
   Q
'
0
28.01.2020, 04:47

Теги

Похожие вопросы