Linux 加速使用多个find命令的bash脚本
我有一个bash脚本,可以将项目的一些文件添加到git中,然后同步该分支,随着文件量的增加,我注意到脚本的速度变慢了很多,所以我想知道我是否以正确的方式执行 这是脚本中添加文件的部分:Linux 加速使用多个find命令的bash脚本,linux,performance,git,bash,find,Linux,Performance,Git,Bash,Find,我有一个bash脚本,可以将项目的一些文件添加到git中,然后同步该分支,随着文件量的增加,我注意到脚本的速度变慢了很多,所以我想知道我是否以正确的方式执行 这是脚本中添加文件的部分: echo "Adding files..." find . -name '*.js' -exec git add {} \; find . -name '*.html' -exec git add {} \; find . -name '*.css' -exec git add {} \; find . -nam
echo "Adding files..."
find . -name '*.js' -exec git add {} \;
find . -name '*.html' -exec git add {} \;
find . -name '*.css' -exec git add {} \;
find . -name '*.py' -exec git add {} \;
find . -name '*.txt' -exec git add {} \;
find . -name '*.jpg' -exec git add {} \;
find . -name '*.sh' -exec git add {} \;
echo "Commit"
git commit -m "'$1'"
我不确定一次调用find是否比使用所有这些单独的命令更快,但我这样做是为了更简单地删除某些类型的文件或添加新的文件
我非常感谢任何建议,以不同的方式使用命令或使用不同的命令来提高效率。如果git支持在一个命令中添加多个文件,最简单的方法就是使用
+
后缀-exec
:
find . -name '*.js' -exec git add {} \+
这将收集大量文件,并将它们全部传递到一个命令行中的命令
因此,将要执行的是:
git add a.js b.js c.js d.js
而不是
git add a.js
git add b.js
git add c.js
git add d.js
如果您正在处理数百或数千个文件,这将大大缩短执行时间
要将所有文件模式组合成一个find
命令,请使用find的“or”运算符:
find . \( -name '*.js' -o \
-name '*.html' -o \
-name '*.css' -o \
-name '*.py' -o \
-name '*.txt' -o \
-name '*.jpg' -o \
-name '*.sh' \) -exec git add {} +
需要使用\
之前的(
和)
来保护它们不受其特殊外壳含义的影响。你也可以用引号来代替:”(“
,”)“
find
有一些复杂的选项,学习和熟悉这些选项需要花费一些精力,但多年来,我通过使用复杂的find
命令,而不是通过grep和awk等过滤文件名,节省了很多精力
我目前最喜欢的扫描maven/subversion java项目而忽略无趣文件的模式之一是:
find . \( \( \( -iname .svn -o -iname target -o -iname classes \) -type d -prune -false \) -o \( <your filter expression> \) \) -exec grep -li xxx {} +
find\(\(\(-iname.svn-o-iname target-o-iname classes\)-type d-prune-false\)-o\(\)-exec grep-li xxx{}+
这可能更快:
F='\.js$|\.html$|\.css$|\.py$|\.txt$|\.jpg$|\.sh$'
find . | egrep $F | xargs git add
如果您希望在文件名中使用空格或其他特殊字符,也可以使用它的一些变体
find . \( -name '*.js' -o \
-name '*.html' -o \
-name '*.css' -o \
-name '*.py' -o \
-name '*.txt' -o \
-name '*.jpg' -o \
-name '*.sh' \) -exec git add {} +
这意味着您只需扫描一次目录结构,这是加速“多个查找s”的主要方法;将“多个”替换为“一个”。+
是posix2008对find
的一个补充,但它更像xargs
。如果你不能使用,请考虑使用<代码>打印< <代码>和<代码> xARGs<代码>(或者,如果你的名字中有空格,你有GNU<代码>查找< /COD>和<代码> XARGS,然后<代码> -PROT00和<代码> XARGS - 0 < /代码>,但是如果你有这些代码,你(也许-但见评论)也有<代码> +<代码> >符号。.如果
- 参加Bash4
- 仅按名称搜索(不按其他条件搜索)
您也可以使用此选项:
shopt -s globstar
git add **/*.{js,html,css,py,txt,jpg,sh}
注:
大括号扩展在文件名扩展之前执行,因此这相当于写入
git add **/*.js **/*.html etc...
globstar
通过关键字**
启用递归文件名扩展
git add
命令可以在不使用任何其他shell脚本的情况下执行此操作
git add -- '*.js' '*.html' '*.css' ...
或者,您可以通过xargs
,最好通过组合find
的开关-print0
和-0
来实现xargs
的输出,这使得它们使用以null结尾的字符串,所以你不必担心转义空格和类似的东西。非常感谢你的详细解释,我现在正在实现它。我使用你在这里展示的代码实现了它,但是我收到一个错误,说“find:missing arguments to'-exec'”,你知道我遗漏了什么吗?@jeruki:在一个相当现代的linux上?(不到10岁?)也许你需要避开+
符号。很难判断脚本是在centos 6和windows机器上运行的,我想问题是第二个,但使用xargs修复了它。如果使用类似的东西,请不要忘记尾随的$和前导\。我犯了这个错误,并丢失了我的Mercurial存储库的历史记录:(如果您在前面花费了一些精力来学习如何使用find
直接进行这种过滤,那么您可以使用-exec选项来执行所需的命令以及“文件名中的空格或其他特殊字符”的困难)这似乎是最清楚的选择,这是否也添加了子目录?好的,我通过尝试/错误找到了递归部分,但后来意识到,如果它没有找到一个扩展名为的文件,那么它会因错误而失败并中止操作,有没有办法告诉它即使模式不匹配也要继续看起来,--忽略错误
应该可以为您做到这一点,但我还没有测试它。我尝试过,但它不起作用,也许忽略错误不会忽略所有类型的错误。我尝试过这一点,发现我的bash版本在find中不支持+,所以我使用了xargs-0,现在工作正常,谢谢