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 functionnameaber ist das der beste Weg?
xargs? Oder die -execprimä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 functionnameaber ist das der beste Weg?
xargs? Oder die -execprimäre in find?
Antworten:
$ find . -type f -print0 | xargs -0 grep foo
$ grep -r foo . # GNU grep only
und in zshmit setopt extendedglob,
$ grep foo **/*(.)
find . -type f -print0 | xargs -0 grep /dev/null foo, damit grepimmer 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).
grepes nicht hatte (die Idee war, dass, wenn Sie Rekursion wollten, Sie findmit verwendet haben grep) und das Hinzufügen nachträglich zu Systemen, die seit Jahren funktionieren, Dinge brechen könnte. (GNU grepverhält sich nicht ganz identisch mit zB System V. grep)
Als Alternative zu den find | xargsAntworten 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 ctagsgegen Ihre Quelle laufen , um eine TAGSDatei zu erstellen , und dann grepgegen die TAGSDatei, die Zeilen im folgenden Format ausspuckt:
{tagname}<Tab>{tagfile}<Tab>{tagaddress}
Wo tagnamewird der Funktionsname enthalten, tagfileist die Datei, in der es sich befindet, und tagaddresswird 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 ackauch - 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 grepVerfügung haben, wird das Erhalten acknoch mehr empfohlen.
grepdiese 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 grepmit 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 findallow 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/nullist so, dass grepder 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
-rin xargsvermeidet die Ausführung des Befehls, wenn keine Eingabe erfolgt ist. Es ist eine GNU-Erweiterung.
Es gibt auch agwelche speziell dafür entwickelt wurden und viel besser als ack. Es ist in den neuesten Debian / Ubuntu-Versionen im Paket silversearcher-ag verfügbar .
findfindet nur Dateinamen , nicht Inhalt.