Получите N-й результат awk

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

Пример команды:

awk '/>23958742<\/PMID>/,/<\/PubmedArticle>/' file.xml

Я хотел бы получить все результаты и увидеть каждый из них отдельно. Как я мог получить N-й матч команды?

2
задан 28 December 2017 в 18:49

1 ответ

Я чувствую, что вы здесь задаете два разных вопроса, поэтому я просто отвечу на оба.

Получить все совпадения

Здесь происходит что-то странное, потому что команда

awk '/>23958742<\/PMID>/,/<\/PubmedArticle>/' <file.xml

уже должна вывести все совпадения, а не только первое. Хотя есть альтернатива (короткая и читаемая версия):

awk '/>23958742<\/PMID>/{f=1}f==1;/<\/PubmedArticle>/{f=0}' <file.xml
awk '/>23958742<\/PMID>/ {f=1}; f==1 {print}; /<\/PubmedArticle>/ {f=0}' <file.xml

Получить N-е совпадение

awk '/>23958742<\/PMID>/{i++}i==2&&k==1;/<\/PubmedArticle>/{k++}' <file.xml
awk '/>23958742<\/PMID>/ {i++}; i==2 && k==1 {print}; /<\/PubmedArticle>/ {k++}' <file.xml

Это будет просто подсчитывать вхождения ваших строк, сохраняя значения в i и k и печатать каждую строку, пока выполняются условия i==2&&k==1. Я выбрал второй блок в качестве примера, для третьего это будет i==3&&k==2. k отсчет идет после условий, потому что я понял, что вы хотели, чтобы обе совпавшие строки также были напечатаны. Если вам нужно только то, что находится между и , строки поиска переворачивают все вокруг:

awk '/<\/PubmedArticle>/{k++}i==2&&k==1;/>23958742<\/PMID>/{i++}' <file.xml
awk '/<\/PubmedArticle>/ {k++}; i==2 && k==1 {print}; />23958742<\/PMID>/ {i++}' <file.xml

Я всегда позволяю оболочке открывать входной файл и назначать его в стандартный поток программы (<file.xml ) потому что это имеет ряд преимуществ, см. здесь . Я нашел помощь здесь и здесь .

Общее решение, предложенное тердоном , таково:

awk -vn=2 '/>23958742<\/PMID>/{i++;k=1}i==n&&k==1;/<\/PubmedArticle>/{k=0}' <file.xml
awk -vn=2 '/>23958742<\/PMID>/ {i++;k=1}; i==n && k==1 {print}; /<\/PubmedArticle>/ {k=0}' <file.xml

Для этого вам просто нужно установить n с опцией -v, например, -vn=2 для второго матча.

1
ответ дан 28 December 2017 в 18:49

Другие вопросы по тегам:

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