Eu sinto que você está fazendo duas perguntas diferentes aqui, então vou responder ambas.
Obter todas as correspondências
Há algo estranho acontecendo aqui, porque o comando
awk '/>23958742<\/PMID>/,/<\/PubmedArticle>/' <file.xml
já deve produzir todas as correspondências em vez de apenas a primeira. Existe uma alternativa (versão curta e legível):
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
Obter o enésimo jogo
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
Isso contará simplesmente as ocorrências de suas strings, salvará as contagens em i
e k
e imprimirá todas as linhas, desde que as condições i==2&&k==1
ainda sejam atendidas. Eu escolhi o segundo bloco como exemplo aqui, para o terceiro seria i==3&&k==2
. A k
count vem após as condições porque eu entendi que você queria que ambas as linhas correspondidas também fossem impressas. Se você quer apenas o que há entre as strings de busca, inverta tudo:
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
Eu sempre deixo o shell abrir o arquivo de entrada e atribuí-lo ao stdin do programa ( <file.xml
) porque isso tem várias vantagens, consulte aqui . Eu encontrei ajuda aqui e here .
Uma solução geral proposta por terdon é esta:
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
Usando isso, você só precisa definir n
com a opção -v
, por exemplo. -vn=2
para o segundo jogo.