-exec和xargs的区别
来源:互联网 发布:程序员培训班怎么样 编辑:程序博客网 时间:2024/04/27 19:55
原文:http://blog.csdn.net/arganzheng/article/details/6260720
当你在命令行执行:
$find . -name 'core' -type f -exec rm {} /;
时,find -exec 命令会对每个匹配的文件执行一个单独的rm操作(execute a separate rm for each one), 正如你手动敲入下面命令:
rm ./bin/corerm ./source/shopping_cart/corerm ./backups/core...
但是使用这种方式,如果有100个文件匹配了,那么就需要启100个进程,一个进程处理一个rm命令。一般来说,其越多进程,意味着越耗性能。我们可以换个思路,我们将要删除文件当作参数传递给rm不就可以了吗?也就是说:
rm ./bin/corerm ./source/shopping_cart/corerm ./backups/core...
改成:
rm ./bin/core ./source/shopping_cart/core ./backups/core
但是前提是后面的命令必须支持多参数。相有些命令,比如unzip,就不支持输入多个jar包,所以必须用-exec。
xargs,顾名思义,是对参数进行处理的命令。它的任务就是将输入行转换成下一个命令的参数列表。因此上面的find -exec命令可以改写成:
find . -name 'core' -type f -print | xargs rm
With this approach, xargs bundles together as many filename arguments as possible for submission to each invocation of rm that's needed, in compliance with the OS's maximum allowed size for an argument list. This means xargs is guaranteed not only to handle all the arguments, but also to use the smallest possible number of processes in doing so. For example, if each command can handle 100 arguments, and there are 110 filenames to process, there will be two invocations of the command, respectively handling 100 and 10 arguments.
其中操作系统允许的最大参数长度由如下命令得到:
forrest@ubuntu:~$ getconf ARG_MAX2097152
这意味着xargs保证不会因为参数过多而挂掉。所以目前看来唯一需要保证的就是后面的命令支持多参数。比如前面说过的unzip,就不支持多参数,如果你使用xargs xxx.jar
forrest@ubuntu:~/work/intl-standalone/searchaddbuild/deploy/WORLDS-INF/lib$ unzip -l alibaba-intl-biz-account-api-1.0-Dev.jarArchive: alibaba-intl-biz-account-api-1.0-Dev.jar Length Date Time Name--------- ---------- ----- ---- 0 2010-11-24 19:43 META-INF/ 147 2010-11-24 19:42 META-INF/MANIFEST.MF 0 2010-11-24 19:42 com/ 0 2010-11-24 19:42 com/alibaba/ 0 2010-11-24 19:42 com/alibaba/intl/ 0 2010-11-24 19:42 com/alibaba/intl/biz/ 0 2010-11-24 19:42 com/alibaba/intl/biz/company/ 。。。 931 2010-11-24 19:42 com/alibaba/intl/biz/member/api/exception/IllegalRegistInfoException.class 1055 2010-11-24 19:42 com/alibaba/intl/biz/member/api/AccountCoreInfoRemoteServiceContainer.class 2030 2010-11-24 19:42 com/alibaba/intl/biz/AccountCenterServicesLocator.class 467 2010-11-24 19:42 META-INF/INDEX.LIST--------- ------- 43764 51 files
但是如果你用xargs unzip,则会得到如下输出:
forrest@ubuntu:~/work/intl-standalone/searchaddbuild/deploy/WORLDS-INF/lib$ ls | xargs unzip -l Archive: activation.jar Length Date Time Name--------- ---------- ----- ------------- ------- 0 0 filesforrest@ubuntu:~/work/intl-standalone/searchaddbuild/deploy/WORLDS-INF/lib$ find . -name "*.jar" -type f | xargs unzip -lArchive: ./poi-scratchpad-3.0.jar Length Date Time Name--------- ---------- ----- ------------- ------- 0 0 files
而使用-exec就没有问题:
forrest@ubuntu:~/work/intl-standalone/searchaddbuild/deploy/WORLDS-INF/lib$ ls -exec unzip -l {} /;ls: invalid option -- 'e'Try `ls --help' for more information.forrest@ubuntu:~/work/intl-standalone/searchaddbuild/deploy/WORLDS-INF/lib$ find . -name "*.jar" -type f -exec unzip -l {} /; 3041 2008-12-16 14:58 freemarker/core/AddConcatExpression$ConcatenatedHashEx.class 1102 2008-12-16 14:58 freemarker/core/AddConcatExpression$ConcatenatedSequence.class 3937 2008-12-16 14:58 freemarker/core/AddConcatExpression.class 1500 2008-12-16 14:58 freemarker/core/AndExpression.class 2463 2008-12-16 14:58 freemarker/core/ArithmeticEngine$BigDecimalEngine.class 8050 2008-12-16 14:58 freemarker/core/ArithmeticEngine$ConservativeEngine.class 。。。
用xargs的-l选项,可以达到跟-exec一样的作用:
forrest@ubuntu:~/work_back/intl-standalone/searchaddbuild/deploy/WORLDS-INF/lib$ find -name "*.jar" | xargs -l unzip -l | grep napoli.properties
404 2010-11-16 17:11 META-INF/autoconf/biz-napoli.properties.vm
666 2010-11-27 01:49 biz/napoli.properties
forrest@ubuntu:~/work_back/intl-standalone/searchaddbuild/deploy/WORLDS-INF/lib$
另外,xargs也用{}表示当前处理的参数:
forrest@ubuntu:~/work_back/intl-standalone/searchaddbuild/deploy/WORLDS-INF/lib$ ls | xargs -t -I {} mv {} {}.oldmv activation.jar activation.jar.old mv activemq-core-5.2.0.jar activemq-core-5.2.0.jar.old 。。。
这一命令序列通过在每个名字结尾添加 .old 来重命名在当前目录里的所有文件。-I 标志告诉 xargs 命令插入有{}(花括号)出现的ls目录列表的每一行。
实战
1. SVN提交代码,如果你用-exec提交每个文件,必然被BS。所以最好是用xargs:
$svn st | grep '^[AMD]' | cut -c9- | xargs svn ci -m "merge: test using xarge"
这样只会有一次提交记录。
2. 将lib下面非jar包删除
forrest@ubuntu:~/work_back/intl-standalone/searchaddbuild/deploy/WORLDS-INF/lib$ ls | sed '/.jar/ d' | xargs rm -rf
3. 查找某个文件是否在jar包中
forrest@ubuntu:~/work_back/intl-standalone/searchaddbuild/deploy/WORLDS-INF/lib$ find -name "*.jar" -exec unzip -l {} /; | grep napoli.properties 404 2010-11-16 17:11 META-INF/autoconf/biz-napoli.properties.vm 666 2010-11-27 01:49 biz/napoli.properties
但是注意到这个结果只能告诉你有这个文件,但是没有告诉你是那个jar包。如果你想知道是哪个jar包,可以用如下命令(这个暴强的命令来自于海锋,我等膜拜):
forrest@ubuntu:~/work_back/intl-standalone/searchaddbuild/deploy/WORLDS-INF/lib$ find -name "*.jar" -exec sh -c 'unzip -l $1 | xargs printf "$1 %s/n"' {} {} /; | grep napoli.properties./alibaba-intl-commons-napoli-1.0-Dev.jar META-INF/autoconf/biz-napoli.properties.vm./alibaba-intl-commons-napoli-1.0-Dev.jar biz/napoli.properties
聪妈提供了一个更简单的命令:
forrest@ubuntu:~/work/intl-standalone/searchaddbuild/deploy/WORLDS-INF/lib$ find . -name "*.jar" | xargs grep napoli.propertiesBinary file ./alibaba-intl-commons-napoli-1.0-Dev.jar matches
达到的效果与xargs非常类似,但是xargs有对命令参数作超长检查,而这个不会。所以不建议在这里使用。但是使用``从上一个命令中获取输入结果是非常有用的。
forrest@ubuntu:~/work_back/intl-standalone/searchaddbuild_trunk/deploy/WORLDS-INF/lib$ unzip -l `find . -name "*.jar"`Archive: ./poi-scratchpad-3.0.jar Length Date Time Name--------- ---------- ----- ------------- ------- 0 0 filesforrest@ubuntu:~/work_back/intl-standalone/searchaddbuild_trunk/deploy/WORLDS-INF/lib$ for i in `find . -name "*.jar"`; do unzip -l $i | grep napoli.properties; done 404 2010-11-16 17:11 META-INF/autoconf/biz-napoli.properties.vm 705 2010-11-26 20:21 biz/napoli.properties
----------------------------------------------------------------------
在一目录下执行rm -rf *时报错如下:bash: /bin/rm: Argument list too long
分析:
rm有最大一次删除的数量,所以当一个目录里有太多的文件或目录时,就会出现错误,或许应该是在两万以下。而使用find ./ |xargs rm -rf的目的是先使用find列出文件,再导向到xargs,xargs再喂给rm,在这里,xargs会分批依照rm的最大数量喂给rm,然后就可以顺利删除文件了。
- -exec和xargs的区别
- -exec和xargs的区别
- 04.08 管道xargs和exec的区别
- linux下-exec和xargs的区别
- exec 与 xargs的区别
- find和xargs、exec、ok的故事
- xargs命令和find的-exec
- linux中exec和xargs命令的区别和优劣分析
- find -exec 与xargs 区别
- find -exec 与xargs 区别
- find -exec 与xargs 区别
- find -exec 与 xargs的区别与使用
- xargs和管道的区别
- xargs和grep的区别
- exec , xargs
- linux下find ... |xargs 和 -exec
- EXEC和sp_executesql的区别
- EXEC和sp_executesql的区别
- poj——1986——Distance Queries
- >/dev/null 2>&1 的作用
- 河南科技学院-第五届网页设计大赛-见面会暨第一次讲课
- 【奶味香蕉蛋羹】
- 第一次新建Android Studio项目,不用在线下载gradle
- -exec和xargs的区别
- Iterator,for,forEach的遍历和效率
- Ubuntu13.10 风扇转速高 关闭独显 降低转速
- Android蓝牙连接远程蓝牙事例
- Linux命令之终端打印 - echo
- Makefile 模板
- 自学者的福音
- sdut 1595 选夫婿2!
- Java字符串之性能优化