原文地址: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命令可以改写成:

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_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的区别相关推荐

  1. linux中fopen和open的区别,Linux下open与fopen的区别

    int open(const char *path, int access,int mode) path 要打开的文件路径和名称 access 访问模式,宏定义和含义如下: O_RDONLY      ...

  2. 有关linux下find和xargs的使用

    使用find和xargs有时可能需要在系统中查找具有某一特征的文件(例如文件权限.文件属主.文件长度.文件类型等等).这样做可能有很多原因.可能出于安全性的考虑,或是一般性的系统管理任务,或许只是为了 ...

  3. linux 下的 source,sh,./三者区别

    前言 工作中遇到的问题,总结一下,参考较多文章总结的,若有错误,望请指出,谢谢! source Linux source命令: 通常用法:source filepath 或 . filepath 它的 ...

  4. Linux下useradd与adduser的区别

    Linux下创建用户时会用到useradd和adduser这两个命令,他们的区别如下: 1.使用useradd时,如果后面不添加任何参数选项,例如:#sudo useradd test创建出来的用户将 ...

  5. linux ide sata硬盘,Linux 下SATA与IDE硬盘区别

    linux下看到的sda字样表示该机器是IDE模式的硬盘,看到sda字样表示机器是SATA模式的硬盘 解析: 使用df -lh(df -h)可以清晰的查看硬盘使用情况 [root@localhost ...

  6. Linux下tmpfs与ramfs的区别

    转自:http://www.linuxidc.com/Linux/2012-11/74356.htm ramfs是Linux下一种基于RAM做存储的文件系统.在使用过程中你就可以把ramfs理解为在普 ...

  7. linux下使用find xargs grep查找文件及文件内容

    原文地址:http://sundful.iteye.com/blog/1730385 1,在某个路径下查文件. 在/etc下查找"*.log"的文件 find /etc -name ...

  8. WINDOWS下与LINUX下写C程序的区别

    要开始编程了,先熟悉下工具,查到的以下资料,有的是说系统区别,有的是说编程区别: 1.如果没有涉及系统独有的库函数或者编程方法(即只用符合ANSI C标准的代码和方法),就没有区别. 如果涉及到系统编 ...

  9. linux 下.bashrc和.profile的区别

    /etc/profile:   这个文件是系统的每个用户设置环境信息,当用户第一次登录时,该文件被执行. 并从/etc/profile.d目录的配置文件中搜集shell的设置. /etc/bashrc ...

最新文章

  1. 爱因斯坦牛顿达尔文投胎中国后
  2. mysql修改字符集utf8为utf8mb4
  3. 由创建一个不能被继承的类引发的对象模型的思考
  4. MFC单文档框架编程(一): 分隔窗口的实现
  5. Jmeter(4)Http Cookie Manager
  6. 从零开始学TensorFlow
  7. leetcode 310. Minimum Height Trees | 310. 最小高度树(图的邻接矩阵DFS / 拓扑排序)
  8. 方案计数(带修计数题/线段树)
  9. 如何在本地管理和切换多个 github 账号?
  10. 水逆的美团滴滴与头条
  11. css3——新盒子定义box-sizing
  12. 在使用vue-video-player时,切换页面浏览器报错:TypeError: this.el_.vjs_getProperty is not a function**
  13. 千月2021全新改版影视app系统源码 影视app全新双端开源系统 全开源 带投屏 带教程
  14. 【HTML】Html页面跳转的5种方式
  15. capsule系列之Dynamic Routing Between Capsules
  16. Microarchitecture: HyperThreading(超线程)
  17. cadence导入dxf文件_Allegro PCB导入DXF文件详解
  18. Unity-Tilemap 瓦片地图
  19. Wine零知识学习1 —— 介绍
  20. android导出txt文件格式,安卓端数据导出成txt文件

热门文章

  1. matlab输入数组换行,三维数组换行输入到文件(intel fortran 编译器) - 程序语言 - 小木虫 - 学术 科研 互动社区...
  2. python几岁开始学_python编程少儿几岁可以学?有哪些优势?
  3. Mysql事务处理问题
  4. OSGI动态加载删除Service bundle
  5. RabbitMQ指南(中)
  6. Python运行报错IndentationError: unindent does not match any outer indentation level
  7. 深度学习(六)caffe入门学习
  8. 鸟哥的Linux私房菜(基础篇)-第三章、主机规划与磁盘分区(三.3. 安装Linux前的规划)
  9. 0330 第九次课:软件包安装及卸载
  10. nosql介绍、memrcached介绍、安装memcached、查看memcachedq状态