SAG challenge (sed, awk, grep): фильтрация файлов по нескольким шаблонам - PullRequest
1 голос
/ 11 октября 2010

Итак, дорогие мои, позвольте мне перейти непосредственно к вопросу: спецификация: отфильтровать текстовый файл, используя пары шаблонов.Пример: если у нас есть файл:

line 1 blabla
line 2 more blabla
line 3 **PAT1a** blabla
line 4 blabla
line 5 **PAT1b** blabla
line 6 blabla
line 7 **PAT2a** blabla
line 8 blabla
line 9 **PAT2b** blabla
line 10 **PAT3a** blabla
line 11 blabla
line 12 **PAT3b** blabla
more and more blabla

должен дать:

line 3 **PAT1a** blabla
line 4 blabla
line 5 **PAT1b** blabla
line 7 **PAT2a** blabla
line 8 blabla
line 9 **PAT2b** blabla
line 10 **PAT3a** blabla
line 11 blabla
line 12 **PAT3b** blabla

Я знаю, как подать только одну его часть, используя 'sed': sed -n-e '/ PAT1a /, / PAT1b / {p}' Но как отфильтровать все фрагменты, нужно ли мне записывать эти пары шаблонов в файл конфигурации, читать пару из него, использовать приведенный выше sed, перейти к следующей паре ...?

Примечание. Предположим, что у PAT1, PAT2, PAT3 и т. д. нет общего префикса (например, в данном случае «PAT»)

Еще одна вещь: каксделать новую строку в тексте квоты в этом сообщении, не оставляя целую пустую строку?

Ответы [ 3 ]

2 голосов
/ 11 октября 2010

Я предположил, что пары шаблонов даны в отдельном файле.Затем, когда они отображаются по порядку на входе, вы можете использовать скрипт awk:

awk 'NR == FNR { a[NR] = $1; b[NR] = $2; next }
     !s && $0 ~ a[i+1] { s = 1 }
     s
     s && $0 ~ b[i+1] { s = 0; i++ }' patterns.txt input.txt

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

awk 'NR == FNR { a[++n] = $1; b[n] = $2; next }
     { for (i = 1; !s && i <= n; i++) if ($0 ~ a[i]) s = i; }
     s
     s && $0 ~ b[s] { s = 0 }' patterns.txt input.txt
0 голосов
/ 11 октября 2010

Используйте команду b, чтобы пропустить все строки между шаблонами, и команду d, чтобы удалить все остальные строки:

sed -e '/PAT1a/,/PAT1b/b' -e '/PAT2a/,/PAT2b/b' -e '/PAT3a/,/PAT3b/b' -e d
0 голосов
/ 11 октября 2010

Awk.

$ awk '/[0-9]a/{o=$0;getline;$0=o"\n"$0;print;next}/[0-9]b/' file
line 3 PAT1a blabla
line 4 blabla
line 5 PAT1b blabla
line 7 PAT2a blabla
line 8 blabla
line 9 PAT2b blabla
line 10 PAT3a blabla
line 11 blabla
line 12 PAT3b blabla

Примечание. Так как вы сказали "не использовать общий префикс", я использую число и шаблон [ab] для регулярных выражений

...