Wie führe ich einen Befehl für mehrere Dateien aus?


12

Dies ist ziemlich einfach. Ich habe einen Ordner mit mehreren Unterordnern von JS-Dateien und möchte den Clojure-Compiler von Google für alle Dateien in diesen Ordnern ausführen. Der Befehl zum Verarbeiten einer einzelnen Datei lautet wie folgt:

java -jar compiler.jar --js filename.js --js_output_file newfilename.js

Wie ändere ich dies, um es auf jeder JS-Datei in meiner Verzeichnisstruktur auszuführen?

Antworten:


13

Sie können verwenden find:

find . -name "*.js" -exec java -jar compiler.jar --js {} --js_output_file new{} \;

Vielen Dank, und ich kann dies wahrscheinlich nutzen, um alles umzubenennen, da die ursprünglichen JS-Dateien überschrieben werden müssen
Mataniko

Falls sich die Dateien --js und --js_output_file unterscheiden müssen, würde ich ein zweizeiliges Skript erstellen, das den Dateinamen als Parameter verwendet, die Ausgabe in eine temporäre Datei und mvdie Datei in den ursprünglichen Namen schreibt .
Anthon

Wenn Sie vermeiden möchten, ein separates Skript zu erstellen, find -name '*.js' | while read jsfile; do java -jar compiler.jar --js "$jsfile" --js_output_file "new$jsfile" && mv "new$jsfile" "$jsfile"; donesollten Sie dies tun.
David Baggerman

find -execist ideal für einfache Befehle. für komplexe find | xargsist viel besser und es ermöglicht auch, Befehle parallel auszuführen.
Eile

@ Rush vielleicht erklären, warum xargsist besser?
Mel Boyce

7

Sie können auch eine einfache forSchleife verwenden, insbesondere wenn sich die Dateien in einem einzelnen Verzeichnis befinden (keine Unterverzeichnisse). Es kann geändert werden, um auch mit Unterverzeichnissen zu arbeiten.

Ohne Rekursion:

for filename in ./*.js
do
    java -jar compiler.jar --js "${filename}" --js_output_file "new${filename}"
done

oder als gleichwertiger Einzeiler:

for filename in ./*.js; do java -jar compiler.jar --js "${filename}" --js_output_file "new${filename}"; done

Um in Unterverzeichnisse zurückzukehren (erfordert GNU Bash 4.0 oder neuer) (danke @ChrisDown ):

shopt -s globstar
for filename in ./**/*.js; do
    java -jar compiler.jar --js "${filename}" --js_output_file "new${filename}"
done

1
Dadurch werden die in der Frage gestellten Unterverzeichnisse nicht wiederholt. Mit bash4 + können Sie dies globstartun.
Chris Down

1
Ja, es ist eine gute Antwort und toll zu wissen, aber die andere Antwort macht genau das, was ich brauche.
Mataniko

1
Ohh, ich habe es geschafft, den Teil "Mehrere Unterordner" komplett zu verpassen. Es tut uns leid. Der Vollständigkeit halber die Antwort jedoch herumlassen.
ein CVn

3
@rush Da **kann eine beliebige Ebene der Rekursion entsprechen, **/*.jsfunktioniert: sprunge.us/PXQK
Chris Down

1
Es ist im Allgemeinen eine gute Idee, for f in ./*.js; dooder for f in ./**/*.js; doum sich vor Dateinamen zu schützen, die mit a beginnen -(ich weiß nicht, ob dies in diesem Fall notwendig ist, aber es ist trotzdem eine gute Angewohnheit).
Evilsoup
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.