Besser anhand von Beispielen erklären.
Ich kann:
find . -name "*.py" -type f > output.txt
Aber wie kann ich die Ausgabe in derselben Datei speichern für:
find . -name "*.py" -type f -exec grep "something" {} \
Ich kann nicht einfach
find . -name "*.py" -type f -exec grep "something" {} \ > output.txt
Antwort
Wenn ich Sie richtig verstehe, möchten Sie Folgendes tun:
find . -name "*.py" -print0 | xargs -0 grep "something" > output.txt
Alle Dateien mit der Erweiterung .py
finden, grep
nur Zeilen, die something
und speichern Sie die Zeilen in output.txt
. Wenn die Datei output.txt
vorhanden ist, wird sie abgeschnitten, andernfalls wird sie abgeschnitten wird erstellt.
Verwenden von -exec
:
find . -name "*.py" -exec grep "something" {} \; > output.txt
Ich verwende Chris Downs Kommentar hier: Der obige Befehl führt dazu, dass grep
so oft ausgeführt wird, wie find
Pfadnamen findet, die die angegebenen Tests bestehen (nur die einzelnen Test oben). Wenn Sie jedoch die \;
durch eine +
ersetzen, wird grep
durch mehrere Pfadnamen aufgerufen von find
(bis zu einer bestimmten Grenze).
Siehe Frage Verwenden von Semikolon (;) vs plus ( +) mit exec in find für weitere Informationen zum Thema.
Kommentare
- Verwenden Sie
+
anstelle von\;
wird die Ausführungszeit erheblich verbessert (da Argumente vor der Ausführung bisARG_MAX
verkettet werden). - Jetzt verstehe ich die Kraft von Xargs! Vielen Dank!
- Verwenden Sie
grep -H
, wenn Sie den Dateinamen der Datei in die Ausgabe aufnehmen möchten. - Verwenden Sie Option 1. Und fügen Sie
LC_ALL=C
direkt vorxargs
, um viel zusätzliche Geschwindigkeit zu erhalten. Und Sie können ein-P6
-Flag aufxargs
verwenden, um parallel zu (in diesem Fall) 6 Prozessen zu laufen (Sie können die Nummer jederzeit ändern von 6 bis etwas höher oder niedriger, um zu sehen, was ' auf Ihrem Computer und bei Ihrer Suche schneller ist). Referenz: unix.stackexchange.com/questions/131535/… - Verwenden von
+
anstelle von\;
übergibt mehrere Dateien an grep, und wenn eine Datei in diesem Satz den Text ' etwas ', alle diese Dateien bestehen den Test. ' macht also nicht das, was Sie wollen.
Antwort
Wenn Sie alle übereinstimmenden Zeilen in allen Dateien in output.txt
speichern möchten, funktioniert Ihr letzter Befehl, außer dass Ihnen die erforderliche ;
am Ende des Befehls.
find . -name "*.py" -type f -exec grep "something" {} \; > output.txt
Wenn jeder Lauf von grep
erzeugt werden soll In eine andere Datei ausgeben, eine Shell ausführen, um den Namen der Ausgabedatei zu berechnen und die Umleitung durchzuführen.
find . -name "*.py" -type f -exec sh -c "grep "something" <"$0" >"$0.txt"" {} \;
Kommentare
- das letzte wirklich schön: D
- Um @gilles zu erweitern, antworten Sie, um es ein wenig informativer zu machen, besonders wenn die Liste der Dateien, die Sie ' Wenn der Umgang mit div groß ist, können Sie den Dateinamen (relativen Pfad) jeder Datei zusammen mit den grep ' ed-Ergebnissen angeben, indem Sie Folgendes verwenden:
find . -name "*.py" -type f -exec grep "something" {} \; -print > output.txt
Und wenn Sie ' sehen möchten Bei den Zeilennummern der grep ' ed-Zeilen können Sie natürlichgrep -n "something"
verwenden. div>
Antwort
Für den Datensatz hat grep
--include
und --exclude
Argumente, mit denen Sie die durchsuchten Dateien filtern können:
grep -r --include="*.py" "something" > output.txt
Kommentare
- Mindestens GNU
grep
tut dies.
Antwort
Verwenden Sie tee
:
find . -name "*.py" | tee output.txt | xargs grep "something"
Die Einschränkung ist, wenn Sie Dateien haben mit Sonderzeichen (einschließlich Leerzeichen), mit denen xargs
und grep
nicht gut funktionieren (a file.txt
wird als zwei Dateien interpretiert, a
und file.txt
). Die Alternative dazu besteht darin, entweder -x
oder -print0
zu verwenden, aber beide verschmutzen Ihre output.txt
. Die -x
verwendet \
, um bestimmte Sonderzeichen zu umgehen, und dies wird in output.txt
sein.Die -print0
verwendet ein Nullbyte als Feldtrennzeichen (für das auch xargs -0
erforderlich ist) und output.txt
sieht aus wie eine lange zusammenhängende Textzeile.
Wie Sie damit umgehen (oder nicht), liegt bei Ihnen.
Antwort
grep -n CThread "`find . -name "*.cpp"`"