Obtenir la dernière correspondance dans un fichier en utilisant grep

58

Quel est le meilleur moyen d'obtenir uniquement la correspondance finale d'une expression régulière dans un fichier à l'aide de grep?

De plus, est-il possible de commencer la recherche de code depuis la fin du fichier au lieu du début et de l'arrêter dès la première correspondance?

Gland
la source

Réponses:

85

Tu pourrais essayer

grep pattern file | tail -1

ou

tac file | grep pattern | head -1

ou

tac file | grep -m1 pattern
Cakemox
la source
20
tac file | grep -m 1 pattern
Dennis Williamson
1
Avec la contrainte supplémentaire que je voulais obtenir le numéro de ligne ( grep -n) dans le fichier réel, je pense tacqu’il fallait quasiment éviter, sauf si je voulais faire une soustraction avec wc -l. Sinon , tacavec grep -m1fait beaucoup de sens.
Nick Merrill
1
J'aimerais voir une version plus performante que celle-ci, car j'essaie de rechercher un fichier de 20 Go.
Jeff
La réponse de @DennisWilliamson est bien meilleure car grepelle cessera de fonctionner après le premier match. sans -m 1, greptrouvera d’abord tous les modèles correspondants dans le fichier , puis headne montrera que le premier - beaucoup moins efficace. Dennis, s'il vous plaît, pensez à poster ceci dans une réponse séparée!
gilad mayani
1

Pour quelqu'un qui travaille avec d'énormes fichiers texte sous Unix / Linux / Mac / Cygwin. Si vous utilisez Windows, vérifiez les outils Linux sous Windows: https://stackoverflow.com/questions/3519738/what-is-the-best-way-to-use-linux-utilities-under-windows .

On peut suivre ce workflow pour avoir de bonnes performances:

  1. compresse avec gzip
  2. utilisez zindex (sur github: https://github.com/mattgodbolt/zindex ) pour indexer le fichier avec la clé appropriée
  3. interroger le fichier indexé à zqpartir du package.

Citation de son readme github:

Créer un index

Il faut indiquer à zindex quelle partie de chaque ligne constitue l’indice. Cela peut être fait par une expression régulière, par champ ou en redirigeant chaque ligne via un programme externe.

Par défaut, zindex crée un index de fichier.gz.zindex lorsqu'il est invité à indexer fichier.gz.

Exemple:

créer un index sur les lignes correspondant à une expression régulière numérique. Le groupe de capture indique la pièce à indexer et les options montrent que chaque ligne a un index numérique unique.

$ zindex file.gz --regex 'id:([0-9]+)' --numeric --unique

Exemple: créez un index sur le deuxième champ d'un fichier CSV:

$ zindex file.gz --delimiter , --field 2 

Exemple:

créez un index sur un champ JSON orderId.id dans l'un des éléments du tableau d'actions de la racine du document (nécessite jq). La requête jq crée un tableau de tous les orderId.ids, puis les joint avec un espace pour garantir que chaque ligne attribuée à jq crée une seule ligne de sortie, avec plusieurs correspondances séparées par des espaces (qui est le séparateur par défaut).

$ zindex file.gz --pipe "jq --raw-output --unbuffered '[.actions[].orderId.id] | join(\" \")'" 

Interrogation de l'index

Le programme zq est utilisé pour interroger un index. On lui donne le nom du fichier compressé et une liste de requêtes. Par exemple:

$ zq file.gz 1023 4443 554 

Il est également possible de sortir par numéro de ligne, donc pour imprimer les lignes 1 et 1000 à partir d'un fichier:

$ zq file.gz --line 1 1000
biocyberman
la source
1

J'utilise toujours le chat (mais cela le rend un peu plus long): cat file | grep pattern | tail -1

Je voudrais blâmer mon professeur de cours d'administration Linux au collège qui aime les chats :))))

- Vous n'êtes pas obligé de commencer par lire un fichier avant de le récupérer. grep pattern file | tail -1et est plus efficace aussi.

Ismail Guneydas
la source
6
Ceci n'est que la première partie de la réponse de Cakemox, sauf pire.
augurar
Cela fonctionne, mais cela fait des étapes inutiles. Pour une utilisation légère, cette solution fonctionne bien mais ne fonctionne pas bien. La raison en est que vous n'avez pas besoin catdu fichier et de le diriger vers grep. Vous pouvez faire greprechercher le fichier directement via grep pattern file(puis utiliser tailpour renvoyer le dernier résultat), comme dans la réponse de Cakemox.
jvriesem