linux下-exec和xargs的区别
原文地址:http://blog.csdn.net/arganzheng/article/details/6260720
-exec和xargs的區別
2010-11-27 星期六 晴朗當你在命令行執行:
$find . -name 'core' -type f -exec rm {} /;
時,find -exec 命令會對每個匹配的文件執行一個單獨的rm操作(execute a separate rm for each one), 正如你手動敲入下面命令:
rm ./bin/core rm ./source/shopping_cart/core rm ./backups/core ...但是使用這種方式,如果有100個文件匹配了,那么就需要啟100個進程,一個進程處理一個rm命令。一般來說,其越多進程,意味著越耗性能。我們可以換個思路,我們將要刪除文件當作參數傳遞給rm不就可以了嗎?也就是說:
rm ./bin/core rm ./source/shopping_cart/core rm ./backups/core ...改成:
rm ./bin/core ./source/shopping_cart/core ./backups/core但是前提是后面的命令必須支持多參數。相有些命令,比如unzip,就不支持輸入多個jar包,所以必須用-exec。
xargs,顧名思義,是對參數進行處理的命令。它的任務就是將輸入行轉換成下一個命令的參數列表。因此上面的find -exec命令可以改寫成:
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_MAX 2097152這意味著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.jar Archive: alibaba-intl-biz-account-api-1.0-Dev.jarLength Date Time Name --------- ---------- ----- ----0 2010-11-24 19:43 META-INF/147 2010-11-24 19:42 META-INF/MANIFEST.MF0 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.class1055 2010-11-24 19:42 com/alibaba/intl/biz/member/api/AccountCoreInfoRemoteServiceContainer.class2030 2010-11-24 19:42 com/alibaba/intl/biz/AccountCenterServicesLocator.class467 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.jarLength Date Time Name --------- ---------- ----- ---- --------- -------0 0 files forrest@ubuntu:~/work/intl-standalone/searchaddbuild/deploy/WORLDS-INF/lib$ find . -name "*.jar" -type f | xargs unzip -l Archive: ./poi-scratchpad-3.0.jarLength 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.class1102 2008-12-16 14:58 freemarker/core/AddConcatExpression$ConcatenatedSequence.class3937 2008-12-16 14:58 freemarker/core/AddConcatExpression.class1500 2008-12-16 14:58 freemarker/core/AndExpression.class2463 2008-12-16 14:58 freemarker/core/ArithmeticEngine$BigDecimalEngine.class8050 2008-12-16 14:58 freemarker/core/ArithmeticEngine$ConservativeEngine.class。。。| ls -exec是有問題的,因為ls會將-e作為它的一個選項解釋,即:ls -e |
| xargs的-l選項 用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 {} {}.old mv 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.properties404 2010-11-16 17:11 META-INF/autoconf/biz-napoli.properties.vm666 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.properties Binary file ./alibaba-intl-commons-napoli-1.0-Dev.jar matches 第三種方式——使用單反引號(``)作命令替換command substitution達到的效果與xargs非常類似,但是xargs有對命令參數作超長檢查,而這個不會。所以不建議在這里使用。但是使用``從上一個命令中獲取輸入結果是非常有用的。
forrest@ubuntu:~/work_back/intl-standalone/searchaddbuild_trunk/deploy/WORLDS-INF/lib$ unzip -l `find . -name "*.jar"` Archive: ./poi-scratchpad-3.0.jarLength Date Time Name --------- ---------- ----- ---- --------- -------0 0 files forrest@ubuntu:~/work_back/intl-standalone/searchaddbuild_trunk/deploy/WORLDS-INF/lib$ for i in `find . -name "*.jar"`; do unzip -l $i | grep napoli.properties; done404 2010-11-16 17:11 META-INF/autoconf/biz-napoli.properties.vm705 2010-11-26 20:21 biz/napoli.properties總結
以上是生活随笔為你收集整理的linux下-exec和xargs的区别的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 明明白白你的Linux服务器——日志篇
- 下一篇: linux 的set,env和expor