Come posso eseguire un comando su più file


13

Questo è piuttosto semplice, ho una cartella con diverse sottocartelle di file JS e voglio eseguire il compilatore Clojure di Google su tutti i file in quelle cartelle. Il comando per elaborare un singolo file è il seguente:

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

Come posso modificarlo per essere eseguito su ogni file JS nella mia struttura di directory?

Risposte:


14

Puoi usare find:

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

Grazie, e probabilmente posso sfruttare questo per rinominare tutto perché i file JS originali devono essere sovrascritti
Mataniko,

Nel caso in cui --js e --js_output_file debbano differire, creerei uno script a due righe che accetta il nome file come parametro, scrivo l'output nel file temporaneo e mvil file con il nome originale.
Anthon,

Se vuoi evitare di creare uno script separato, find -name '*.js' | while read jsfile; do java -jar compiler.jar --js "$jsfile" --js_output_file "new$jsfile" && mv "new$jsfile" "$jsfile"; donedovresti fare il trucco.
David Baggerman,

find -execè ottimo per comandi semplici. per quelli complessi find | xargsè molto meglio e consente anche di eseguire comandi in parallelo.
precipita il

@rush forse spiega perché xargsè meglio?
Mel Boyce,

7

Puoi anche usare un semplice forciclo, specialmente se i file si trovano in una singola directory (nessuna sottodirectory). Può essere modificato per funzionare anche con le sottodirectory.

Senza ricorsione:

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

o come equivalente one-liner:

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

Per ricorrere alle sottodirectory (richiede GNU bash 4.0 o successive) (grazie a @ChrisDown ):

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

1
Ciò non fa riferimento alle sottodirectory richieste nella domanda. Con bash4 +, puoi usare globstarper farlo.
Chris Down,

1
Sì, è una buona risposta e ottima da sapere, ma l'altra risposta fa esattamente quello di cui ho bisogno.
Mataniko,

1
Oh, sono riuscito a perdere completamente la parte "diverse sottocartelle". Scusate. Lasciare la risposta in giro per completezza, però.
un CVn il

3
@rush Dato che **può corrispondere a un livello arbitrario di ricorsione, **/*.jsfunziona: sprunge.us/PXQK
Chris Down

1
In genere è una buona idea usare for f in ./*.js; doo for f in ./**/*.js; doper proteggersi dai nomi di file che iniziano con un -(non so se sia necessario in questo caso, ma è comunque una buona abitudine).
evilsoup,
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.