Frage

Ich möchte ein Bash-Befehl finden, die mir jede Datei in einem Verzeichnis grep lassen und die Ausgabe dieses grep in eine separate Datei schreiben. Meine Vermutung gewesen wäre, so etwas zu tun

ls -1 | xargs -I{} "grep ABC '{}' > '{}'.out"

aber, soweit ich weiß, xargs nicht wie die doppelten Anführungszeichen. Wenn ich die doppelten Anführungszeichen entfernen, aber dann leitet der Befehl die Ausgabe des gesamten Befehl in einer einzigen Datei namens ‚{}‘. Out statt einer Reihe von einzelnen Dateien.

Kennt jemand eine Möglichkeit, dies mit xargs zu tun? Ich habe nur dieses grep Szenario als Beispiel für mein Problem mit xargs so irgendwelche Lösungen dar, die xargs nicht nicht als zutreffend für mich verwenden sind.

War es hilfreich?

Lösung

Sie machen den Fehler nicht, dies zu tun:

sh -c "grep ABC {} > {}.out"

Dies wird unter vielen Bedingungen brechen, einschließlich flippigen Dateinamen und ist unmöglich, richtig zu zitieren. Ihre {} muss immer ein einziges völlig getrenntes Argument für den Befehl Code-Injektion um Fehler zu vermeiden. Was Sie tun müssen, ist dies:

xargs -I{} sh -c 'grep ABC "$1" > "$1.out"' -- {}

Gilt sowie xargs find.

Durch die Art und Weise, niemals xargs ohne -0 Option (es sei denn, für sehr seltene und einmalige interaktive Nutzung gesteuert, wo Sie nicht Sorgen um Ihre Daten zu zerstören).

Auch analysieren nicht ls. Je. Verwenden Sie Globbing oder find statt: http://mywiki.wooledge.org/ParsingLs

Verwenden find für alles, was sonst für alles Rekursion und eine einfache Schleife mit einem glob benötigt:

find /foo -exec sh -c 'grep "$1" > "$1.out"' -- {} \;

oder nicht-rekursive:

for file in *; do grep "$file" > "$file.out"; done

Beachten Sie die ordnungsgemäße Verwendung der Anführungszeichen.

Andere Tipps

Eine Lösung ohne xargs ist die folgende:

find . -mindepth 1 -maxdepth 1 -type f -exec sh -c "grep ABC '{}' > '{}.out'" \;

... und das gleiche getan werden kann, mit xargs, es stellt sich heraus:

ls -1 | xargs -I {} sh -c "grep ABC '{}' > '{}.out'"

Bearbeiten : Apostrophe nach Bemerkung hinzugefügt von lhunath .

Ich gehe davon aus Ihrem Beispiel ist nur ein Beispiel, und dass Sie für andere Dinge brauchen> können. GNU Parallel http://www.gnu.org/software/parallel/ können Ihre Rettung sein . Es braucht keine zusätzliche Angabe, solange Ihre Dateinamen enthalten keine \ n:

ls | parallel "grep ABC {} > {}.out"

Wenn Sie Dateinamen mit \ n drin:

find . -print0 | parallel -0 "grep ABC {} > {}.out"

Als zusätzlichen Bonus erhalten Sie die Jobs parallel ausgeführt werden.

Bearbeiten.

Sie können GNU installieren Parallel einfach durch:

wget http://git.savannah.gnu.org/cgit/parallel.git/plain/src/parallel
chmod 755 parallel

Das Intro Videos ansehen, mehr zu lernen: http://pi.dk/1

10 Sekunden Installation:

wget pi.dk/3 -qO - | sh -x
Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top