ฉันจะรันคำสั่งบนหลายไฟล์ได้อย่างไร


13

นี่เป็นพื้นฐานที่ค่อนข้างฉันมีโฟลเดอร์ที่มีโฟลเดอร์ย่อยหลายไฟล์ของ JS และฉันต้องการเรียกใช้คอมไพเลอร์ Clojure ของ Google ในไฟล์ทั้งหมดในโฟลเดอร์เหล่านั้น คำสั่งในการประมวลผลไฟล์เดียวมีดังนี้:

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

ฉันจะแก้ไขสิ่งนี้ให้ทำงานกับทุกไฟล์ JS ในโครงสร้างไดเรกทอรีของฉันได้อย่างไร

คำตอบ:


14

คุณสามารถใช้find:

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

ขอขอบคุณและฉันอาจใช้ประโยชน์จากสิ่งนี้เพื่อเปลี่ยนชื่อทุกอย่างเพราะไฟล์ JS ดั้งเดิมต้องถูกเขียนทับ
Mataniko

ในกรณีที่ --js และ --js_output_file ต้องแตกต่างกันฉันจะสร้างสคริปต์สองบรรทัดที่ใช้ชื่อไฟล์เป็นพารามิเตอร์เขียนเอาต์พุตไปยังไฟล์ชั่วคราวและmvไฟล์เป็นชื่อเดิม
Anthon

หากคุณต้องการหลีกเลี่ยงการสร้างสคริปต์แยกfind -name '*.js' | while read jsfile; do java -jar compiler.jar --js "$jsfile" --js_output_file "new$jsfile" && mv "new$jsfile" "$jsfile"; doneควรทำเคล็ดลับ
David Baggerman

find -execดีมากสำหรับคำสั่งง่ายๆ สำหรับคอมเพล็กซ์find | xargsนั้นดีกว่ามากและมันยังอนุญาตให้รันคำสั่งแบบขนาน
เร่ง

@ รัชอาจอธิบายได้ว่าทำไมถึงxargsดีกว่า
Mel Boyce

7

คุณยังสามารถใช้การforวนรอบแบบง่ายโดยเฉพาะอย่างยิ่งหากไฟล์อยู่ในไดเรกทอรีเดียว (ไม่มีไดเรกทอรีย่อย) มันสามารถปรับเปลี่ยนให้ทำงานกับไดเรกทอรีย่อยได้เช่นกัน

ไม่มีการเรียกซ้ำ:

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

หรือเทียบเท่าหนึ่งซับ:

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

ในการเรียกคืนไปยังไดเรกทอรีย่อย (ต้องใช้ GNU bash 4.0 หรือใหม่กว่า) (ขอบคุณ@ChrisDown ):

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

1
สิ่งนี้จะไม่เรียกคืนไดเรกทอรีย่อยตามที่ถามในคำถาม ด้วย bash4 + คุณสามารถใช้globstarในการทำเช่นนั้น
Chris Down

1
ใช่มันเป็นคำตอบที่ดีและยอดเยี่ยมที่จะรู้ แต่คำตอบอื่น ๆ ทำในสิ่งที่ฉันต้องการ
Mataniko

1
โอ้ฉันพลาดส่วน "โฟลเดอร์ย่อยหลายแห่ง" อย่างสมบูรณ์ ขอโทษ แม้ว่าจะต้องทิ้งคำตอบไว้เพื่อความสมบูรณ์
CVn

3
@rush เนื่องจาก**สามารถจับคู่ระดับการเรียกซ้ำตามอำเภอใจได้**/*.jsผล: sprunge.us/PXQK
Chris Down

1
โดยทั่วไปควรใช้for f in ./*.js; doหรือfor f in ./**/*.js; doเพื่อป้องกันตัวเองจากชื่อไฟล์ที่ขึ้นต้นด้วย-(ฉันไม่รู้ว่าจำเป็นในกรณีนี้ แต่เป็นนิสัยที่ดีอยู่แล้ว)
evilsoup
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.