Ich suche nach einem Funktionsnamen und die Ordnerstruktur ist tief und es gibt viele Dateien zu suchen.
Normalerweise gehe ich mit so etwas wie, find * | grep functionname
aber ist das der beste Weg?
xargs
? Oder die -exec
primäre in find
?
Ich suche nach einem Funktionsnamen und die Ordnerstruktur ist tief und es gibt viele Dateien zu suchen.
Normalerweise gehe ich mit so etwas wie, find * | grep functionname
aber ist das der beste Weg?
xargs
? Oder die -exec
primäre in find
?
Antworten:
$ find . -type f -print0 | xargs -0 grep foo
$ grep -r foo . # GNU grep only
und in zsh
mit setopt extendedglob
,
$ grep foo **/*(.)
find . -type f -print0 | xargs -0 grep /dev/null foo
, damit grep
immer der passende Dateiname gedruckt wird. Oder find . -type f -exec grep /dev/null {} +
für Implementierungen, die POSIX.2004 eingeholt haben (was derzeit OpenBSD ausschließt).
grep
es nicht hatte (die Idee war, dass, wenn Sie Rekursion wollten, Sie find
mit verwendet haben grep
) und das Hinzufügen nachträglich zu Systemen, die seit Jahren funktionieren, Dinge brechen könnte. (GNU grep
verhält sich nicht ganz identisch mit zB System V. grep
)
Als Alternative zu den find | xargs
Antworten können Sie auch die Verwendung von ctags in Betracht ziehen, da Sie nicht nach Text, sondern speziell nach Funktionsnamen suchen.
Um dies zu tun, würden Sie ctags
gegen Ihre Quelle laufen , um eine TAGS
Datei zu erstellen , und dann grep
gegen die TAGS
Datei, die Zeilen im folgenden Format ausspuckt:
{tagname}<Tab>{tagfile}<Tab>{tagaddress}
Wo tagname
wird der Funktionsname enthalten, tagfile
ist die Datei, in der es sich befindet, und tagaddress
wird ein vi-Befehl sein, um zu dieser Zeile zu gelangen. (Könnte nur eine Zeilennummer sein.)
(Gibt es eine einfache Möglichkeit, mit den verschiedenen von Eclipse erstellten Indizes etwas Ähnliches zu tun oder einfach die Eclipse-Datenbank abzufragen?)
Was ist los mit grep -r
(== grep --recursive
)? Vermisse ich hier etwas?
(+1 ack
auch - ich benutze regelmäßig beide)
edit: Ich habe einen ausgezeichneten Artikel gefunden, der die Möglichkeiten und Fallstricke beschreibt, wenn Sie nicht GNU grep
hier haben . Aber im Ernst, wenn Sie nicht zur GNU grep
Verfügung haben, wird das Erhalten ack
noch mehr empfohlen.
grep
diese Option nicht hat. aktualisierte meine Antwort :)
find . | xargs grep
schlägt bei Dateinamen mit Leerzeichen fehl:
> echo test > "a b c"
> find . | xargs grep test
grep: ./a: No such file or directory
grep: b: No such file or directory
grep: c: No such file or directory
Beachten Sie, dass auch -print0 dieses Problem hat.
Meiner Meinung nach ist es besser, -exec grep
mit find zu arbeiten, das alle Dateinamen intern behandelt und dieses Problem vermeidet:
> find . -exec grep test {} \;
test
>
find … -print0 | xargs -0 …
kommt mit beliebigen Dateinamen zurecht. Alle POSIX.2004-kompatiblen Implementierungen von find
allow find … -exec … {} +
, die den Befehl mit mehreren Dateien gleichzeitig aufrufen . Ein besserer Befehl ist find . -type f -exec grep test /dev/null {} +
; Das Hinzufügen von /dev/null
ist so, dass grep
der Dateiname konsistent gedruckt wird, wenn eine Übereinstimmung gefunden wird.
Wenn Ihre Festplatten schnell sind, möchten Sie möglicherweise das grep parallelisieren:
find . -type f -print0 | parallel -0 grep foo
Sehen Sie sich das Intro-Video an, um mehr über GNU Parallel zu erfahren: http://www.youtube.com/watch?v=OpaiGYxkSuQ
$ find -type f -print0 | xargs -r0 grep foo
-r
in xargs
vermeidet die Ausführung des Befehls, wenn keine Eingabe erfolgt ist. Es ist eine GNU-Erweiterung.
Es gibt auch ag
welche speziell dafür entwickelt wurden und viel besser als ack
. Es ist in den neuesten Debian / Ubuntu-Versionen im Paket silversearcher-ag verfügbar .
find
findet nur Dateinamen , nicht Inhalt.