Existe-t-il un moyen d’effectuer un grep en fonction des résultats d’un précédent, au lieu de simplement empiler plusieurs greps les uns dans les autres. Par exemple, disons que j'ai la sortie du fichier journal ci-dessous:
ID 1000 xyz occured
ID 1001 misc content
ID 1000 misc content
ID 1000 status code: 26348931276572174
ID 1000 misc content
ID 1001 misc content
Pour commencer, je voudrais grep le fichier de journal entier pour voir si "xyz s'est produit" est présent. Si c'est le cas, j'aimerais obtenir le numéro d'identification de cet événement et grep via toutes les lignes du fichier portant ce numéro d'identification, à la recherche du code d'état.
J'imaginais pouvoir utiliser xargs ou quelque chose du genre, mais je n'arrive pas à le faire fonctionner.
grep "xyz occured" file.log | awk '{ print $2 }' | xargs grep "status code" | awk '{print $NF}'
Des idées sur comment faire cela?
Tu y es presque. Mais si xargs peut parfois être utilisé pour faire ce que vous voulez (en fonction de la façon dont la commande suivante prend ses arguments), vous ne l'utilisez pas réellement pour grep pour l'ID que vous venez d'extraire. Ce que vous devez faire, c'est prendre la sortie du premier grep (contenant le code d'identification) et l'utiliser dans la prochaine expression de grep. Quelque chose comme:
grep "^ID `grep 'xyz occured' file.log | awk '{print $2}'` status code" file.log
Évidemment, une autre option serait d'écrire un script pour le faire en un seul passage, comme le suggère Ed.
Une réponse générale pour grep-ing la sortie grep-ed:
grep 'patten1' *.txt | grep 'pattern2'
remarquez que le second grep ne pointe pas sur un fichier.
En savoir plus sur les trucs cool de grep ici
Grep le résultat d'un précédent Grep:
Étant donné le contenu de ce fichier:
ID 1000 xyz occured
ID 1001 misc content
ID 1000 misc content
ID 1000 status code: 26348931276572174
ID 1000 misc content
ID 1001 misc content
Cette commande:
grep "xyz" file.log | awk '{ print $2 }' > f.log; grep `cat f.log` file.log;
renvoie ceci:
ID 1000 xyz occured
ID 1000 misc content
ID 1000 status code: 26348931276572174
ID 1000 misc content
Il recherche "xyz" dans fichier.log place le résultat dans f.log. Puis greps pour cet identifiant dans file.log. Si le grep externe renvoie plusieurs identifiants, alors le grep interne ne cherchera que le premier identifiant et les autres en erreur.
Encore une autre façon
for x in `grep "xyz occured" file.log | cut -d\ -f2`
do
grep $x file.log
done
Ce que j’aime dans cette méthode, c’est que si vous le vouliez, vous pourriez écrire la sortie dans un fichier pour chaque code de statut.
grep $x file.log >> /var/tmp/$x.out
Il suffit d'utiliser awk:
awk '{info[$2] = info[$2] $0 ORS} /xyz occured/{ids[$2]} END{ for (id in ids) printf "%s",info[id]}' file.log
ou:
awk '/status code/{code[$2]=$NF} /xyz occured/{ids[$2]} END{ for (id in ids) print code[id]}' file.log
en fonction de ce que vous voulez vraiment sortir. Certains résultats attendus dans votre question pourraient aider.
Il s’agit simplement de récupérer les fichiers dans une zone de recherche plus étroite. Dans votre cas, l'étendue de la recherche est déterminée par le contenu du fichier.
J'ai trouvé ce problème plus souvent tout en réduisant l'étendue de la recherche grâce à de nombreuses recherches (application de filtres aux résultats précédents de grep).
Essayer de trouver une réponse générale:
1) Générez une liste avec le résultat du premier grep:
grep pattern | awk -F':' '{print $1}'
2) Deuxième grep dans la liste des fichiers comme ici
xargs grep -i pattern
3) appliquez ce filtre en cascade les fois où vous avez juste besoin d’ajouter awk pour n’obtenir que les noms de fichiers et xargs
pour les transférer à grep -i
Par exemple:
grep 'pattern1' | awk -F':' '{print $1}' | xargs grep -i 'pattern2'