Linux 加速使用多个find命令的bash脚本

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

我有一个bash脚本,可以将项目的一些文件添加到git中,然后同步该分支,随着文件量的增加,我注意到脚本的速度变慢了很多,所以我想知道我是否以正确的方式执行

这是脚本中添加文件的部分:

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,现在工作正常,谢谢