it-swarm.com.de

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

Mögliches Duplikat:
Suche nach einem Textmuster unter Linux

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?

41
Dark Templar

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-grep kann auch unter OSX installiert werden, die ausführbare Datei heißt jedoch nur ack.

60

Das Standardwerkzeug für die Textsuche ist grep .

So suchen Sie in allen toUpperCase(-Dateien im aktuellen Verzeichnis nach der Zeichenfolge .c:

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 Datei TAGS von ctags verwenden. Wenn Sie Emacs verwenden, führen Sie das ähnliche Programm etags aus.

10
Gilles

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

Vorhersehbar gibt es sieben Antworten, die bereits sagen, dass grep verwendet werden soll. Aber ich scheine die einzige Person zu sein, die von Ihrer Frage bemerkt hat, dass Sie vim verwenden. Obwohl Sie grep innerhalb von vim verwenden können , können Sie auch das integrierte Tool von vim verwenden. Dies wird über den Befehl :vimgrep aufgerufen.

Um "alle C-Quelldateien im aktuellen Verzeichnis nach Aufrufen der Funktion toUpperCase()" zu durchsuchen, geben Sie den Befehl vim 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 Funktionsdefinition zu finden, anstatt sie aufzurufen, ist ctags das Werkzeug, wie in der Antwort Gilles erwähnt . -) in Verbindung mit den Befehlen :tjump oder :tselect.

Warum :vimgrep verwenden?

In der Online-Hilfe (:help grep) sind einige der Gründe aufgeführt, die ich hier nicht beschreiben möchte. Vergleichen Sie außerdem die Aktion von :vimgrep mit der Antwort von dietbuddha . Die Befehlszeile von dietbuddha gibt einen individuellen grep-Prozess für jede einzelne C-Quelldatei aus. Es werden nicht einmal xargs verwendet, um diesen Overhead zu reduzieren. Und Sie müssen die Ausgabe noch irgendwie analysieren, um Ihren Texteditor für die relevanten Quelldateien aufzurufen, sobald diese fertig sind. :vimgrep spaltet überhaupt nicht mehrere zusätzliche Prozesse ab, und die Verwendung des Ergebnisses ist einfach. 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 (mit der gleichen regulären Ausdruckssyntax, die Sie bereits an anderer Stelle in vim verwenden) und zeichnet die Stellen auf, an denen Übereinstimmungen auftreten, und entlädt dann die Datei.

6
JdeBP

Ja, das Tool heißt 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 Option -r an. Wenn Ihnen Groß- oder Kleinschreibung egal ist, können Sie mit der Option -i die Groß- und Kleinschreibung ignorieren.

grep -ri "touppercase()" .

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

Grep kann reguläre Ausdrücke verwenden und hat ein großes Handbuch .

3
slhck

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

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/

2
Doug Harris

find UND grep

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

warum nicht nur grep?

grep -r string . durchsucht 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 zu unbekannten/unbeabsichtigten Konsequenzen führen.

grep string *.c durchsucht nur die .c-Dateien des aktuellen Verzeichnisses.

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

1
dietbuddha

Grep erledigt 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
0
Tim Brigham

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

0
SnoopDougieDoug