Durchsuchen mehrerer Zeichenfolgen in mehreren Dateien in einem Verzeichnis und Drucken der Zeichenfolge und des entsprechenden Dateinamens, in dem sie gefunden wurde

Durchsuchen mehrerer Zeichenfolgen in mehreren Dateien in einem Verzeichnis und Drucken der Zeichenfolge und des entsprechenden Dateinamens, in dem sie gefunden wurde

Ich habe etwa 500 Zeichenfolgen und möchte in einem Verzeichnis nach den Dateien suchen, die diese Zeichenfolgen enthalten, und die Dateinamen abrufen, die die Zeichenfolgen enthalten. Bisher habe ich Folgendes verwendet:

find -name 'LYFNRE.*' -exec grep -f file1.txt {} \; -print

Das Problem besteht jedoch darin, dass eine Zeichenfolge in vielen Dateien enthalten sein kann. Aufgrund der enormen Ausgabemenge ist es daher schwierig herauszufinden, welche Zeichenfolgen vorhanden sind und welche fehlen. Können Sie mir helfen, die Zeichenfolgen mit den entsprechenden Dateinamen dort auszudrucken, wo sie gefunden wurden?

Antwort1

Sie sollten sich einfach grepdie Dateinamen zuweisen lassen. GNU grepkann das:

grep -HFf ../strings.txt *

Sie erhalten eine Ausgabe, die etwa wie folgt aussieht:

[filename]:[matched_line]

...für jede Übereinstimmung mit jeder Datei im Verzeichnis. Sie können auch Zeilennummern abrufen:

grep -HnFf ../strings.txt *

...der bereitstellt...

[filename]:[line_number]:[matched_line]

Antwort2

Das Problem besteht darin, dass Sie jeweils nur eine Datei an übergeben grep. Wenn grepin der Befehlszeile eine einzelne Datei angezeigt wird, geht das Programm davon aus, dass Sie genau wissen, wo Sie suchen. Daher wird der Dateiname vor Übereinstimmungen nicht angezeigt.

Ein Trick, um grepdie Ausgabe eines Dateinamens immer zu erzwingen, besteht darin, auch „pass“ zu verwenden /dev/null(wobei es nie eine Übereinstimmung geben wird). Einige Grep-Implementierungen haben dafür eine Option: -H.

Zusätzlich können Sie -exec … {} +anstelle von verwenden -exec … {} \;, um das Programm für mehrere Dateien auf einmal auszuführen. Das ist schneller. Sie sollten trotzdem /dev/nulloder übergeben -H, da es vorkommen kann, dass der Befehl für genau eine Datei aufgerufen wird, entweder weil es eine einzige passende Datei gibt oder weil es viele Übereinstimmungen gibt, die erfordern, dass grepes mehrmals aufgerufen wird und einmal zufällig eine einzelne Datei betrifft.

find -name 'LYFNRE.*' -exec grep -f file1.txt /dev/null {} +

GNU grep und aktuelle BSD-Implementierungen (einschließlich OSX) unterstützen Optionen zum greprekursiven Aufruf ohne dass dies erforderlich ist find.

grep -R --include='LYFNRE.*' -f file1.txt -H .

Alternativ können Sie rekursives Globbing in Ihrer Shell durchführen. In zsh funktioniert dies sofort. In bash müssen Sie es shopt -s globstarzuerst ausführen und beachten, dass bash (anders als findbei zsh) durch symbolische Links zu Verzeichnissen rekursiv vorgeht.

grep -f file1.txt /dev/null **/LYFNRE.*

Antwort3

verwenden Sie egrep:

egrep -n "str1|str2|str3" file_names

-n druckt die Zeilennummer in der spezifischen Datei, in der die Zeichenfolge gefunden wurde

verwandte Informationen