Bash: Gibt es eine Möglichkeit, in einem Dateiverzeichnis nach einer bestimmten Zeichenfolge zu suchen? [Duplikat]

47

Mögliches Duplizieren:
Suchen Sie unter Linux nach einem Textmuster

In Bash habe ich mich gefragt, ob es Befehle gibt, mit denen Sie wissen können, ob eine bestimmte Zeichenfolge, nach der Sie suchen, in den Dateien im aktuellen Verzeichnis vorhanden ist, in dem Sie sich befinden.

Angenommen, Sie suchen in einem Satz von C-Dateien in Ihrem aktuellen Verzeichnis nach der Funktion 'toUpperCase ()'. Es gibt viele Dateien, daher möchten Sie nicht jede manuell mit vim öffnen und nach der Zeichenfolge 'toUpperCase' suchen, da dies viel Zeit in Anspruch nehmen würde. Wenn dies keine Bash-Befehlszeile ist, gibt es eine andere Methode, um dies effizient durchzuführen?

Dunkler Templer
quelle

Antworten:

64

Mit grep:

grep -R "toUppercase()" *

Oder, wenn Sie ack-grep installiert haben, einfach:

ack-grep "toUppercase"

Wenn Sie die Suche in C-Dateien einschränken möchten, mit ack-grep:

ack-grep -cc "toUppercase()"

ack-grepkann auch unter OSX installiert werden, aber die ausführbare Datei heißt nur ack.

Trasplazio Garzuglio
quelle
So sehr, dass SO bereits eine verdächtig ähnliche Frage hat ;)
David Perry
10

Das Standardwerkzeug für die Textsuche ist grep .

So suchen Sie toUpperCase(in allen .cDateien im aktuellen Verzeichnis nach der Zeichenfolge :

grep -F 'toUpperCase(' *.c

Wenn Sie auch in Unterverzeichnissen suchen möchten:

grep -r --include='*.c' -F 'toUpperCase('

Wenn Sie nach C-Funktionsaufrufen suchen, sind ctags möglicherweise besser geeignet. Sie führen es einmal für alle Ihre Quelldateien aus, um einen Index der Bezeichner zu erstellen, und verwenden dann Ihren Editor, um zwischen den Aufrufen zu navigieren. Alle vi-ähnlichen Editoren können die TAGSDatei von ctags verwenden. Wenn Sie Emacs verwenden, führen Sie das ähnliche Programm aus etags.

Gilles 'SO - hör auf böse zu sein'
quelle
ctagsist für die Suche nach Funktion nützliche Definitionen , nicht Funktion Anrufe .
JdeBP
6

Du benutzt Vim. Sie haben ein eingebautes Tool, um dies zu tun.

Vorhersehbar gibt es sieben Antworten, die bereits zur Verwendung sagen grep. Aber ich scheine die einzige Person zu sein, die von Ihrer Frage bemerkt hat, dass Sie verwenden vim. Als solches, wenn auch Sie können Verwendung grepvon innen vim, können Sie auch verwenden , vims‘integrierte Tool. Dies wird über den :vimgrepBefehl aufgerufen .

Um "alle C-Quelldateien im aktuellen Verzeichnis nach Aufrufen der Funktion zu durchsuchen", geben Sie toUpperCase()den vimBefehl ein

:vimgrep "\<toUpperCase\_s*(" *.c

Die resultierende Liste der Übereinstimmungen wird automatisch in die Quickfix-Liste geladen, auf die mit einer der folgenden Optionen zugegriffen werden kann (in der Online-Hilfe finden Sie den subtilen Unterschied).

:copen
:cwin

Um die Funktion zu finden Definition , anstatt Anrufe es, ctagsist das Werkzeug, wie in der genannten Gilles‚s Antwort , in Verbindung mit der :tjumpoder :tselectBefehlen.

Warum benutzen :vimgrep?

Die Online-Hilfe ( :help grep) zählt einige der Gründe auf, auf die ich hier nicht näher eingehen möchte. Vergleichen Sie außerdem die Aktion von :vimgrepmit der dietbuddhaAntwort von . dietbuddhaDie Befehlszeile von gibt einen individuellen grepProzess für jede einzelne C-Quelldatei aus. Es wird nicht einmal eingesetzt, xargsum diesen Aufwand zu reduzieren. Und Sie müssen die Ausgabe noch irgendwie analysieren, um Ihren Texteditor für die relevanten Quelldateien aufzurufen, sobald er fertig ist. :vimgrepFork nicht mehrere zusätzliche Prozesse überhaupt, und mit dem Ergebnis ist die Einfachheit selbst. Das bloße Auswählen eines der Einträge in der resultierenden Quickfix-Liste positioniert den Cursor automatisch in der entsprechenden Zeile der entsprechenden Quelldatei.

In der Tat macht es genau das, was Sie geschrieben haben, was Sie von Hand tun würden, außer automatisch. Es ist die automatisierte Methode, um genau diese Texteditor-Aktionen auszuführen. Es lädt die Datei wie von Hand, sucht nach einem regulären Ausdruck (unter Verwendung derselben Syntax für reguläre Ausdrücke, die Sie bereits an anderer Stelle verwenden vim), zeichnet die Stellen auf, an denen Übereinstimmungen auftreten, und entlädt die Datei.

JdeBP
quelle
2

Ja, das Tool wird aufgerufen grep.

Der Befehl grep durchsucht eine oder mehrere Eingabedateien nach Zeilen, die mit einem bestimmten Muster übereinstimmen. Standardmäßig druckt grep die übereinstimmenden Zeilen.

Grundsätzliche Verwendung ist:

grep something somewhere

Oder genauer:

grep [some options] pattern file

In einem sehr einfachen Fall möchten Sie rekursiv alle Dateien durchsuchen und geben daher die -rOption an. Wenn Sie sich nicht für Groß- oder Kleinbuchstaben interessieren, können Sie die -iOption verwenden , um die Groß- und Kleinschreibung zu ignorieren.

grep -ri "touppercase()" .

Wenn Sie nur die passenden Teile wünschen, verwenden Sie die -oOption.

Grep kann reguläre Ausdrücke verwenden und verfügt über ein umfangreiches Handbuch .

slhck
quelle
2

grepist die Standardantwort. Verwenden Sie entweder die Option -r, um rekursiv oder in Verbindung mit zu suchen find(Diskussion und Beispiele in anderen Fragen auf dieser Site, z. B. dieser ).

Meine bevorzugte Wahl in letzter Zeit ist ack. Es ist wahrscheinlich nicht auf Ihrem Computer installiert, aber Sie können es mit apt-get auf Ubuntu installieren oder einfach herunterladen. Links, Anleitungen und Gründe, die besser sind als grep, finden Sie unter http://betterthangrep.com/

Doug Harris
quelle
1

find und grep

find myproject -name '*.c' -exec grep 'toUpperCase(' {} \; -print

warum nicht nur grep?

grep -r string .Durchläuft alle Dateien im aktuellen Verzeichnis. Wenn Sie Objektdateien oder andere Binärdateien haben, erhalten Sie möglicherweise eine Übereinstimmung mit binären Ergebnissen, auch bekannt als. Müll. Wenn sich in Ihrem Unterverzeichnis auch Fifos oder Gerätedateien befinden, kann dies unbekannte / unbeabsichtigte Folgen haben.

grep string *.cdurchsucht nur die aktuellen Verzeichnisdateien .c.

grep string **/*.c durchsucht alle Unterverzeichnisse. Wenn Sie jedoch über eine sehr große Anzahl von .cDateien verfügen, besteht die Gefahr, dass die maximale Anzahl von Erweiterungen für den Shell-Glob überschritten wird. Die Erweiterung muss auch zuerst geschehen, was bedeutet, dass vor dem grepBeginn ein vollständiger Baumdurchlauf durchgeführt wird .

dietbuddha
quelle
0

Grep macht den Trick, aber ein bisschen zusätzliches Scripting hilft dabei, den Namen der Datei und die genaue Zeile zu finden, auf die verwiesen wird. Wenn es das ist, was Sie wollen, finde ich, dass das folgende gut funktioniert. Ich habe es als Shell-Skript gespeichert und den gewünschten Wert als erste Befehlszeilenoption übergeben.

for i in $(ls)
do
    cat $i 2> /dev/null | grep $1 > /dev/null 2>&1
    STATUS=$?
    if [ $STATUS  -eq 0 ] ; then
        echo $i
        cat $i | grep -n $1
    fi
done
Tim Brigham
quelle
3
grep hat eine -H Option, die dies bereits tut. grep -Hn was auch immer *
Roy Rico
Lerne jeden Tag etwas Neues. Danke @Roy Rico
Tim Brigham
0

Ich finde es interessant, dass niemand Ihre spezifische Frage beantwortet hat: "Wie finde ich, ob eine bestimmte Zeichenfolge in den Dateien im aktuellen Verzeichnis vorhanden ist". Soweit ich weiß, gibt es keine grep-Option, die nur zurückgibt, ob eine Übereinstimmung in einer Gruppe von Dateien gefunden wurde. Die nächstgelegene Option ist -l, um die Dateinamen aufzulisten. Die naheliegendste Antwort stammt von Tim, mit einigen kleinen Verbesserungen:

#!/usr/bin/bash

for i in $(ls *.c 2> /dev/null)
do
    cat $i 2> /dev/null | grep $1 > /dev/null 2>&1
    STATUS=$?

    if [ $STATUS  -eq 0 ] ; then
        echo "Found"
        exit
    fi
done

echo "Not found"

Sie können dieses Shell-Skript allgemeiner gestalten, indem Sie ein zweites Argument für die Dateierweiterung akzeptieren, ohne zu viel Mühe zu haben.

doug

SnoopDougieDoug
quelle