如何在多个文件上运行命令


13

这是非常基本的操作,我有一个文件夹,其中包含JS文件的几个子文件夹,并且我想在这些文件夹中的所有文件上运行Google的Clojure编译器。处理单个文件的命令如下:

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

如何修改它以在目录结构中的每个JS文件上运行?

Answers:


14

您可以使用find

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

谢谢,我可能可以利用它来重命名所有内容,因为原始的JS文件需要被覆盖
Mataniko 2013年

如果--js和--js_output_file需要不同,我将制作一个两行脚本,以文件名作为参数,将输出写入临时文件,mv并将文件写入原始名称。
Anthon 2013年

如果您要避免创建单独的脚本,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 2013年

find -exec非常适合简单的命令。对于复杂的find | xargs命令要好得多,并且还允许并行运行命令。
2013年

@rush也许解释为什么xargs更好?
梅尔·博伊斯

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它。
克里斯·

1
是的,这是一个很好的答案,并且很高兴知道,但是另一个答案正是我需要的。
Mataniko

1
哦,我设法完全错过了“几个子文件夹”部分。抱歉。不过,为了完整起见,请留下答案。
CVn

3
@rush因为**可以匹配任意级别的递归,所以**/*.js可以运行:sprunge.us/PXQK
Chris Down

1
使用for f in ./*.js; dofor f in ./**/*.js; do为了保护自己免受文件名开头的影响,通常是一个好主意-(在这种情况下,我不知道这是否有必要,但是无论如何都是一个好习惯)。
evilsoup
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.