Ich versuche, grep gegen eine Liste von ein paar hundert Dateien auszuführen:
$ head -n 3 <(cat files.txt)
admin.php
ajax/accept.php
ajax/add_note.php
Obwohl ich nach einer Zeichenfolge greife, von der ich weiß, dass sie in den Dateien enthalten ist, werden die Dateien nicht durchsucht:
$ grep -i 'foo' <(cat files.txt)
$ grep -i 'foo' admin.php
The foo was found
Ich kenne das -f
Flag, das die Muster aus einer Datei liest . Aber wie liest man die Eingabedateien ?
Ich hatte über die schreckliche Umgehung nachgedacht, die Dateien in ein temporäres Verzeichnis zu kopieren, das cp
das <(cat files.txt)
Format zu unterstützen scheint , und von dort aus die Dateien zu durchsuchen. Shirley, es gibt einen besseren Weg.
quelle
while
die Zeilen von file.txt als solche empfangen werden konnten.while
empfängt die Zeilen aus der Datei nicht genau,read
tut das;while
Lass uns das einfach in einer Schleife machen. Die Schleife endet, wenn einread
Fehler auftritt (dh ein Rückkehrcode ungleich Null zurückgegeben wird), normalerweise weil das Dateiende erreicht ist.IFS= read -r filename
,read filename
ist etwas anderes.-H
eine GNU-Erweiterung ist. Sie vermissen einige--
.Angenommen, Dateien sind leer oder durch Zeilenumbrüche getrennt (wobei Anführungszeichen oder Backslashes verwendet werden können, um diese Trennzeichen zu umgehen). Mit GNU können
xargs
Sie das Trennzeichen angeben-d
(wodurch die Behandlung von Zitaten jedoch deaktiviert wird).Angenommen, Dateien sind durch Leerzeichen, Tabulatoren oder Zeilenumbrüche getrennt (dies ist nicht zu vermeiden, obwohl Sie ein anderes Trennzeichen auswählen können, indem Sie es zuweisen
IFS
). Dieser wird fehlschlagen, wenn die Dateiliste auf den meisten Systemen zu groß ist.Diese gehen auch davon aus, dass keine der Dateien aufgerufen wird
-
.quelle
$(< file)
als$(cat file)
, zumindest inbash
undzsh
.Um eine Liste der Dateinamen von stdin zu lesen, können Sie verwenden
xargs
. Z.B,xargs
Liest standardmäßig Elemente aus der Standardeingabe, die durch Leerzeichen getrennt sind. Das-d'\n'
weist es an, newline als Argumentbegrenzer zu verwenden, damit Dateinamen mit Leerzeichen verarbeitet werden können. (Wie Stéphane Chazelas betont, ist das eine GNU-Erweiterung). Es wird jedoch nicht mit Dateinamen mit Zeilenumbrüchen fertig; Wir brauchen einen etwas komplizierteren Ansatz, um damit umzugehen.FWIW, dieser Ansatz ist etwas schneller als eine
while read
Schleife, da der bash-read
Befehl sehr langsam ist - er liest seine Daten zeichenweise, während erxargs
seine Eingabe effizienter liest. Außerdemxargs
ruft nur dengrep
Befehl so oft , wie es braucht, bei jedem Aufruf mehr Dateinamen empfängt, und das ist effizienter als Aufrufgrep
individuell für jeden Dateinamen.Weitere Informationen finden Sie in der xargs-Manpage und auf der xargs-Infoseite.
quelle
xargs
files.txt
Mit der folgenden Option können Sie Elemente aus einer Datei (wie Ihrer Liste) lesen :Das sollte also auch funktionieren:
oder für Leerzeichen in Dateinamen
quelle
Sie können auch ein für machen, aber Orions Beispiel ist das einfachste:
(Führen Sie für jede in der Datei files.txt aufgeführte Datei den Befehl grep aus.)
quelle