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 bis ARG_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 vor xargs, um viel zusätzliche Geschwindigkeit zu erhalten. Und Sie können ein -P6 -Flag auf xargs 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 '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ürlich grep -n "something"

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"`" 

Schreibe einen Kommentar

Deine E-Mail-Adresse wird nicht veröffentlicht. Erforderliche Felder sind mit * markiert.