Làm cách nào để chạy lệnh trên nhiều tệp


13

Điều này khá cơ bản, tôi có một thư mục với một vài thư mục con của các tệp JS và tôi muốn chạy trình biên dịch Clojure của Google trên tất cả các tệp trong các thư mục đó. Lệnh xử lý một tệp như sau:

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

Làm cách nào để sửa đổi điều này để chạy trên mọi tệp JS trong cấu trúc thư mục của tôi?

Câu trả lời:


14

Bạn có thể sử dụng find:

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

Cảm ơn, và tôi có lẽ có thể tận dụng điều này để đổi tên mọi thứ vì các tệp JS gốc cần được ghi đè
Mataniko

Trong trường hợp --js và --jsDefput_file cần khác nhau, tôi sẽ tạo một tập lệnh hai dòng lấy tên tệp làm tham số, ghi đầu ra vào tệp tạm thời và mvtệp vào tên gốc.
Anthon

Nếu bạn muốn tránh tạo một tập lệnh riêng biệt find -name '*.js' | while read jsfile; do java -jar compiler.jar --js "$jsfile" --js_output_file "new$jsfile" && mv "new$jsfile" "$jsfile"; donethì nên thực hiện thủ thuật.
David Baggerman

find -execlà tuyệt vời cho các lệnh đơn giản. đối với những cái phức tạp thì find | xargstốt hơn nhiều và nó cũng cho phép chạy các lệnh song song.
vội vàng

@rush có thể giải thích tại sao xargstốt hơn?
Mel Boyce

7

Bạn cũng có thể sử dụng một forvòng lặp đơn giản , đặc biệt nếu các tệp nằm trong một thư mục (không có thư mục con). Nó có thể được sửa đổi để làm việc với các thư mục con là tốt.

Không có đệ quy:

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

hoặc như một lớp lót tương đương:

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

Để truy xuất vào các thư mục con (yêu cầu GNU bash 4.0 hoặc mới hơn) (cảm ơn @ChrisDown ):

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

1
Điều này không tái diễn các thư mục con như được hỏi trong câu hỏi. Với bash4 +, bạn có thể sử dụng globstarđể làm như vậy.
Chris Xuống

1
Đúng, đó là một câu trả lời hay và tuyệt vời để biết, nhưng câu trả lời khác thực hiện chính xác những gì tôi cần nó.
Mataniko

1
Ồ, tôi đã hoàn toàn bỏ lỡ phần "vài thư mục con". Lấy làm tiếc. Mặc dù vậy, để lại câu trả lời cho sự hoàn chỉnh.
một CVn

3
@rush Vì **có thể khớp với mức đệ quy tùy ý, **/*.jstác phẩm: spunge.us/PXQK
Chris Down

1
Nói chung, nên sử dụng for f in ./*.js; dohoặc for f in ./**/*.js; dođể bảo vệ bản thân khỏi tên tập tin bắt đầu bằng một -(Tôi không biết nếu điều đó là cần thiết trong trường hợp này, nhưng dù sao đó cũng là một thói quen tốt).
evilsoup
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.