Jak uruchomić polecenie na wielu plikach


13

Jest to dość proste, mam folder z kilkoma podfolderami plików JS i chcę uruchomić kompilator Clojure Google na wszystkich plikach w tych folderach. Polecenie przetworzenia pojedynczego pliku jest następujące:

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

Jak zmodyfikować to, aby działało na każdym pliku JS w mojej strukturze katalogów?

Odpowiedzi:


14

Możesz użyć find:

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

Dzięki i prawdopodobnie mogę to wykorzystać, aby zmienić nazwę wszystkiego, ponieważ oryginalne pliki JS muszą zostać zastąpione
Mataniko

W przypadku, gdy pliki --js i --js_output_file muszą się różnić, stworzyłbym dwuwierszowy skrypt, który przyjmuje nazwę pliku jako parametr, zapisuje dane wyjściowe do pliku tymczasowego, a mvplik do oryginalnej nazwy.
Anthon

Jeśli chcesz uniknąć tworzenia osobnego skryptu find -name '*.js' | while read jsfile; do java -jar compiler.jar --js "$jsfile" --js_output_file "new$jsfile" && mv "new$jsfile" "$jsfile"; done, załatw sprawę.
David Baggerman

find -execdoskonale nadaje się do prostych poleceń. dla złożonych find | xargsjest znacznie lepszy, a także pozwala na równoległe uruchamianie poleceń.
pędzi

@ pośpiech może wyjaśnić, dlaczego xargsjest lepszy?
Mel Boyce

7

Możesz także użyć prostej forpętli, szczególnie jeśli pliki znajdują się w jednym katalogu (bez podkatalogów). Można go zmodyfikować, aby działał również z podkatalogami.

Bez rekurencji:

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

lub jako równoważny jednowarstwowy:

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

Aby przejść do podkatalogów (wymaga GNU bash 4.0 lub nowszej wersji) (dzięki @ChrisDown ):

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

1
Nie rekursuje podkatalogów, jak zadano w pytaniu. W bash4 + możesz globstarto zrobić.
Chris Down

1
Tak, to dobra odpowiedź i dobrze wiedzieć, ale druga odpowiedź robi dokładnie to, czego potrzebuję.
Mataniko

1
Och, udało mi się całkowicie przeoczyć część „kilka podfolderów”. Przepraszam. Pozostawiając jednak odpowiedź ze względu na kompletność.
CVn

3
@rush Ponieważ **może pasować do dowolnego poziomu rekurencji, **/*.jsdziała: sprunge.us/PXQK
Chris Down

1
Zasadniczo warto używać for f in ./*.js; dolub for f in ./**/*.js; dow celu ochrony przed nazwami plików zaczynającymi się od -(nie wiem, czy jest to konieczne w tym przypadku, ale i tak jest to dobry nawyk).
evilsoup
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.