web-dev-qa-db-fra.com

Grep que le premier match et arrêter

Je cherche un répertoire de manière récursive en utilisant grep avec les arguments suivants dans l'espoir de ne renvoyer que la première correspondance. Malheureusement, il retourne plus d'un - en fait deux la dernière fois que j'ai regardé. Il semble que j'ai trop d'arguments, surtout sans obtenir le résultat souhaité. : - /

# grep -o -a -m 1 -h -r "Pulsanti Operietur" /path/to/directory

résultats:

Pulsanti Operietur
Pulsanti Operietur

Peut-être que grep n'est pas le meilleur moyen de le faire? Vous me dites, merci beaucoup.

269
Tim Kamm

-m 1 signifie retourner la première correspondance dans un fichier donné. Mais il continuera toujours à rechercher dans d'autres fichiers. De plus, s'il y a deux ou plusieurs correspondants dans la même ligne, ils seront tous affichés.

Vous pouvez utiliser head -1 pour résoudre ce problème:

grep -o -a -m 1 -h -r "Pulsanti Operietur" /path/to/dir | head -1

explication de chaque option grep:

-o, --only-matching, print only the matched part of the line (instead of the entire line)
-a, --text, process a binary file as if it were text
-m 1, --max-count, stop reading a file after 1 matching line
-h, --no-filename, suppress the prefixing of file names on output
-r, --recursive, read all files under a directory recursively
423
mvp

Vous pouvez diriger grep result vers head conjointement avec stdbuf.

Notez que pour garantir l’arrêt après la N-correspondance, vous devez utiliser stdbuf pour vous assurer que grep ne mette pas en tampon sa sortie:

stdbuf -oL grep -rl 'pattern' * | head -n1
stdbuf -oL grep -o -a -m 1 -h -r "Pulsanti Operietur" /path/to/dir | head -n1
stdbuf -oL grep -nH -m 1 -R "Django.conf.urls.defaults" * | head -n1

Dès que head consomme une ligne, il se termine et grep recevra SIGPIPE car il restera toujours quelque chose à diriger alors que head sera parti.

Cela supposait qu'aucun nom de fichier ne contienne newline.

28
Venkat Kotra

Mon programme semblable à un grep-a ack a une option -1 qui s’arrête à la première correspondance trouvée. Il prend en charge le -m 1 auquel @mvp fait également référence. Je l'ai mis là parce que si je cherche dans un grand arbre de code source pour trouver quelque chose que je sais n'existe dans un seul fichier, il est inutile de le trouver et de taper Ctrl-C.

21
Andy Lester

Un seul liner, utilisant find:

find -type f -exec grep -lm1 "PATTERN" {} \; -a -quit
2
Yam Marcovic