web-dev-qa-db-fra.com

Obtenir le nième résultat de awk

J'essaie de trouver du texte entre deux modèles et cela fonctionne. Mais parfois, j'ai plus d'un événement, et il me faudrait tout récupérer et utiliser celui que je veux.

Exemple de commande:

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

Je voudrais obtenir tous les résultats et voir chacun séparément. Comment pourrais-je obtenir la Nième correspondance de la commande?

2
César

J'ai l'impression que vous posez deux questions différentes ici, alors je vais simplement y répondre.

Obtenez tous les matchs

Il se passe quelque chose de bizarre ici, parce que la commande

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

already devrait afficher toutes les correspondances au lieu de la première seule. Il existe cependant une alternative (version courte et lisible):

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

Obtenez le match Nth

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

Cela comptera simplement les occurrences de vos chaînes, sauvegardera les comptes dans i et k et imprimera chaque ligne tant que les conditions i==2&&k==1 seront toujours remplies. J'ai choisi le deuxième bloc comme exemple ici, pour le troisième, il s'agirait de i==3&&k==2. Le compte k vient après les conditions parce que j'avais compris que vous vouliez également que les deux lignes correspondantes soient imprimées. Si vous voulez seulement ce qui est entre la chaîne de recherche retourne le tout:

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

Je laisse toujours le shell ouvrir le fichier d'entrée et l'assigner au stdin du programme (<file.xml) car il présente de nombreux avantages, voir ici . J'ai trouvé de l'aide ici et ici .

Une solution générale proposée par terdon est la suivante:

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

Pour cela, il vous suffit de définir n avec l'option -v, par exemple. -vn=2 pour le deuxième match.

1
dessert