it-swarm.com.de

Grep nur das erste Match und hör auf

Ich suche ein Verzeichnis rekursiv mit grep mit den folgenden Argumenten, in der Hoffnung, nur die erste Übereinstimmung zurückzugeben. Leider gibt es mehr als eins zurück - tatsächlich zwei, als ich das letzte Mal nachgeschaut habe. Es scheint, als hätte ich zu viele Argumente, insbesondere ohne das gewünschte Ergebnis zu erzielen. : - /

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

kehrt zurück:

Pulsanti Operietur
Pulsanti Operietur

Vielleicht ist grep nicht der beste Weg, dies zu tun? Du sagst mir, vielen Dank.

269
Tim Kamm

-m 1 bedeutet, dass die erste Übereinstimmung in einer bestimmten Datei zurückgegeben wird. Es wird jedoch weiterhin in anderen Dateien gesucht. Befinden sich zwei oder mehr Übereinstimmungen in derselben Zeile, werden alle angezeigt.

Sie können head -1 verwenden, um dieses Problem zu lösen:

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

erklärung der einzelnen grep-Optionen:

-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

Sie können grep result an head in Verbindung mit stdbuf weiterleiten.

Beachten Sie, dass Sie zum Stoppen nach der N-ten Übereinstimmung stdbuf verwenden müssen, um sicherzustellen, dass grep die Ausgabe nicht puffern:

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

Sobald head 1 Zeile belegt, wird es beendet und grep wird SIGPIPE empfangen, da es noch etwas zum Pipeen ausgibt, während head weg ist.

Dies setzt voraus, dass keine Dateinamen Zeilenvorschub enthalten.

28
Venkat Kotra

Mein grep-a-like-Programm ack hat eine -1 -Option, die beim ersten gefundenen Treffer endet. Es unterstützt auch den -m 1, auf den @mvp verweist. Ich füge es dort ein, denn wenn ich in einem großen Quelltextbaum nach etwas suche, von dem ich weiß, dass es nur eine Datei gibt, muss ich es nicht finden und Strg-C drücken.

21
Andy Lester

Ein einzelner Liner mit find:

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