#regex #awk
Вопрос:
Я пытаюсь исключить текстовые блоки, когда возникает определенное условие.
Файлы имеют такую компоновку:
- name: Sedan
tags:
- DIGIT
- ABC
- DEF
- YES
- name: Combi
tags:
- DIGIT
- ABC
- DEF
- NO
- nane: SUV
tags:
- DIGIT
- DEF
- YES
- nane: OTHER
tags:
- DIGIT
- ABC
- YES
Условие: ABC amp;amp; !DEF
Итак, печатайте только тот текст-блок, который будет находиться только ABC
в блоке.
Это должно дать мне эту распечатку:
- nane: OTHER
tags:
- DIGIT
- ABC
- YES
Моя первая попытка была чем-то вроде этого:
awk '/^- name:/ { if (found amp;amp; value) {print value} found=value="" } { value=(value?value ORS:"")$0 } /ABC/ amp;amp; !/DEF/ { found=1 } END { if (found amp;amp; value) { print value } }' file
Но вышеприведенная попытка печатает каждый текстовый блок с обоими узорами!
Оба приведенных ниже решения работают, и вот как я использую их для этого для нескольких файлов:
for i in `find /home/ -mindepth 1 -type f ! -empty`; do ln=`awk -v RS='(^|n)- ' '/- ABC(n|$)/ amp;amp; !/- DEF(n|$)/ {printf "- %sn", $0}' $i; printf $i`; echo -e $ln"n" | sed -n -e 's/^.*file: //p' | grep txt ; done
Спасибо
Ответ №1:
Используя gnu-awk
, вы можете разделить файл на записи, используя сначала -
в каждом блоке:
awk -v RS='(^|n)- ' '/- ABC/ amp;amp; !/- DEF/ {printf "- %s", $0}' file
- nane: OTHER
tags:
- DIGIT
- ABC
- YES
Или, чтобы сделать это более точным:
awk -v RS='(^|n)- ' '
/- ABC(n|$)/ amp;amp; !/- DEF(n|$)/ {printf "- %s", $0}
' file
Комментарии:
1. Да, это работает! Я также обновлю свой вопрос о том, как я буду использовать его в цикле for.
Ответ №2:
Обычно я не являюсь поклонником нескольких экземпляров awk/sed/grep
в конвейере, но эти проблемы, похоже, подходят для этого. Во-первых, вставьте пустые строки в качестве разделителей записей. Затем отфильтруйте. Затем удалите пустые строки:
awk '/^-/{print ""} 1' input | awk '/ABC/ amp;amp; !/DEF/' RS= | sed '/^$/d'
Некоторые версии awk
допускают многосимвольный RS, но этот конвейер кажется достаточно простым для использования с теми реализациями awk
, которые не поддерживают это расширение.
Но, похоже , лучшим решением было бы преобразовать yaml в json, затем отфильтровать с jq
помощью, а затем преобразовать обратно в yaml.