xargs是一条Unix类Unix操作系统的常用命令。它的作用是将参数列表转换成小块分段传递给其他命令,以避免参数列表过长的问题[1]

例如,下面的命令:

rm `find /path -type f`

如果path目录下文件过多就会因为“参数列表过长”而报错无法执行。但改用xargs以后,问题即获解决。

find /path -type f -print0 | xargs -0 rm

本例中xargs将find产生的长串文件列表拆散成多个子串,然后对每个子串调用rm。-print0表示输出以null分隔(-print使用换行);-0表示输入以null分隔。这样要比如下使用find命令效率高的多。

find /path -type f -exec rm '{}' \;

上面这条命令会对每个文件调用"rm"命令。当然使用新版的"find"也可以得到和"xargs"命令同样的效果:

find /path -type f -exec rm '{}' +

xargs的作用一般等同于大多数Unix shell中的反引号,但更加灵活易用,并可以正确处理输入中有空格等特殊字符的情况。对于经常产生大量输出的命令如findlocategrep来说非常有用。

find . -name "*.foo" | xargs grep bar

该命令大体等价于

grep bar `find . -name "*.foo"`
find . -name "*.foo" -print0 | xargs -0 grep bar

使用了GNU特殊规定的空字符。

find . -name "*.foo" -print0 | xargs -0 -t -r vi

与上面的基本相同但启动vi进行编辑。-t参数会提前打印错误信息。-r参数是一个GNU扩展,表明在无输入情况下则不构造命令执行。

find . -name "*.foo" -print0 | xargs -0 -i mv {} /tmp/trash

使用-i参数将{}中内容替换为列表中的内容。

转自:http://zh.wikipedia.org/wiki/Xargs

常见使用

我常常见到将find和xargs组合使用以对find返回的文件列表执行某些操作。

更新:根据Twitter和hacker news上的反馈,find是个很强大的命令,它自己也有-exec和-delete这样的参数可以用来执行命令和删除文件,尽管如此,如果你对find的这些选项不太了解,或是想不起来-exec那古怪的语法,那么你还是可以使用更为简单的xargs,并且xargs在效率上也更胜一筹。

递归查找所有Python文件并统计文件行数

find . -name '*.py' | xargs wc -l

递归查找所有Emacs备份文件并删除:

find . -name '*~' | xargs rm

递归查找所有Python文件并搜索import语句:

find . -name '*.py' | xargs grep 'import'

处理文件/目录名中的空格

上面的例子有一个问题,如果文件或是目录名含有空格,则可能会有些问题,这是因为xargs默认会按照空白自负来划分输入。一个简单的解决办法就是告诉find使用NUL(\0)来分割结果(通过向find提供-print0选项),并且告诉xargs也使用Nul来分隔输入(-0)

删除备份文件,即使含有空格:

find . -name '*~' -print0 | xargs -0 rm

demo:有一个test3 .txt,带有空格的文件)

Administrator@ZGC ~
$ find -name '*.txt' | xargs grep hello
grep: ./hello.txt: Is a directory
./test1.txt:hello world!
./test1.txt:hello
./test2.txt:hello world!
grep: ./test3: No such file or directory
grep: .txt: No such file or directory)

改正后:

Administrator@ZGC ~
$ find -name '*.txt' -print0| xargs -0 grep hello
grep: ./hello.txt: Is a directory
./test1.txt:hello world!
./test1.txt:hello
./test2.txt:hello world!
./test3 .txt:hello world!
./test3 .txt:hello

参数位置

上面的例子中xargs从标准输入读取所有非空的元素并将他们连接起来提供给给定的命令进行执行,这在很多情况下会非常有用,尽管如此,有时你可能想要在命令中间插入一个参数,此时-J标记就排上用场了,xargs会为-J参数后面的字符串加上输入然后在执行。

将所有备份文件复制到backups目录下:

find . -name '*~' -print0 | xargs -0 -J % cp % ~/backups

最大命令长度

有时通过管道传递给xargs的输入可能会造成要执行的命令超出最大命令行长度限制,你可以通过下面的命令得到命令行的最大长度:

getconf ARG_MAX

为了避免越限,xargs对于结果命令有它自己的最大长度限制,如果提供的参数有可能会造成调用的命令超出长度限制,则xargs会将输入分割成多个部分,并多次调用目标命令,默认的长度限制是4096,这可能要远远小于大多数现在系统的ARG_MAX设置,你可以通过向xargs提供-s标识来覆盖这个默认设置,当你对一个很大的源代码仓库进行操作时,这会显得尤其有用。

指定参数数量

如果你要执行的命令只接受1个或是2个参数,比如使用diff命令来对2个文件进行比较,那么xargs的-n选项就会非常有用,它可以指定一次向目标命令提供几个参数,如果参数数量多于你制定的数量,则命令将会被重复调用,直到所有输入都已经得到执行。注意,最后一次调用的参数有可能会少于指定的参数数量,下面让我们来看一个简单的例子:

$ echo {0..9} | xargs -n 2

0 1

2 3

4 5

6 7

8 9

同样的,你也可以使用-L参数制定每次只对某几行的输入进行操作,比如-L 1将每次从输入中取一行作为参数传递给待执行的命令,当然,你可以将1改为任意行,但1是最常用的,下面这条命令将演示如何得到每个git commit的代码变化:

git log --format="%H %P" | xargs -L 1 git diff

并行执行命令

你或许会使用xargs调用某些需要密集计算的命令,如果xargs可以利用你电脑上的多核计算能力,那该有多美妙?没错,-P参数就是干这个的,通过这个参数xargs可以一次并行的调用多个命令,举个例子,你可以通过它来并行的运行多个ffmpeg编码器,不过,还是让我们来个更简单一点的例子吧:

并行休眠

$ time echo {1..5} | xargs -n 1 -P 5 sleep

real 0m5.013suser 0m0.003ssys 0m0.014s

线性休眠

$ time echo {1..5} | xargs -n 1 sleep

real 0m15.022suser 0m0.004ssys 0m0.015s

如果你对使用xargs进行并行计算感兴趣,那么你或许应该看看GNU parallel,相比较而言,xargs的优势就是大多数系统默认都支持它,并且在BSD和OS X上也可以很容易的安装,但是parallel则有许多非常赞的特性。

如果你发现这篇帖子有用,别忘了在Twitter Follow下我哦。

-----------

本文来自“Things you (probably) didn’t know about xargs

参考:http://heikezhi.com/yuanyi/things-you-didnt-know-about-xargs

linux xargs 使用的更多相关文章

  1. linux xargs 命令详解

    xargs是给命令传递参数的一个过滤器,也是组合多个命令的一个工具.它把一个数据流分割为一些足够小的块,以方便过滤器和命令进行处理.通常情况下,xargs从管道或者stdin中读取数据,但是它也能够从 ...

  2. Linux xargs 命令

    xargs xargs 是给命令传递参数的一个过滤器,也是组合多个命令的一个工具. xargs 可以将管道或标准输入(stdin)数据转换成命令行参数,也能够从文件的输出中读取数据. xargs 也可 ...

  3. [Linux] xargs 和 管道符的区别

    今天刚好遇到需要使用xargs的情况,就来研究一下xargs 和 管道符的区别 举几个例子,下面两个语句执行后的结果是什么呢? 1. zhang$ find . -name "*.prope ...

  4. [Linux] xargs

    xargs 命令可以将一个命令的输出,作为另一个命令的输入! 这里听来好像是管道的功能,之所以有xargs是因为有的命令不知吃管道,这时xargs就派上用场了! 具体的方法是:前一个命令的输出会使用空 ...

  5. Linux xargs将输出数据流转换成命令参数

    200 ? "200px" : this.width)!important;} --> 介绍 我们可以利用管道将一个命令的“标准输出”作为另一个命令的“标准输入”:但是这里的 ...

  6. [Linux] xargs的- n1参数

    起因在对一堆*.tar.gz文件解压缩时,发现tar xvfz *.tar.gz不管用,一查,原来是tar xvfz *.tar.gz会被shell给拆成tar xvfz a.tar.gz b.tar ...

  7. linux xargs参数

    xargs是给命令传递参数的一个过滤器,也是组合多个命令的一个工具.它把一个数据流分割为一些足够小的块,以方便过滤器和命令进行处理.通常情况下,xargs从管道或者stdin中读取数据,但是它也能够从 ...

  8. Linux xargs命令

    xargs是给命令传递参数的一个过滤器,也是组合多个命令的一个工具.它把一个数据流分割为一些足够小的块,以方便过滤器和命令进行处理.通常情况下,xargs从管道或者stdin中读取数据,但是它也能够从 ...

  9. linux xargs【转】

    -i -I 参数区别 http://man.linuxde.net/xargs 它们都是用来作参数扩展替换的,以下两句代码其实效果一样 cat arg.txt|xargs -i sh sk.sh -p ...

随机推荐

  1. Activity被回收导致fragment的getActivity为null的解决办法

    这两天一直被这个问题困扰,假如app长时间在后台运行,再点击进入会crash,而且fragment页面有重叠现象,让我十分不爽.研究了一天,终于明白其中的原理并加以解决.解决办法如下: 如果系统内存不 ...

  2. bash与sh的区别

    在shell脚本的开头往往有一句话来定义使用哪种sh解释器来解释脚本.目前研发送测的shell脚本中主要有以下两种方式:(1) #!/bin/sh(2) #!/bin/bash在这里求教同福客栈的各位 ...

  3. MongoDB命令行操作

    本文专门介绍MongoDB的命令行操作.其实,这些操作在MongoDB官网提供的Quick Reference上都有,但是英文的,为了方便,这里将其稍微整理下,方便查阅. 这里用来做测试的是远端(10 ...

  4. Leetcode:linked_list_cycle

    一.     题目 给定一个链表.确定它是否有一个环.不使用额外的空间? 二.     分析 1. 空链表不成环 2. 一个节点自环 3. 一条链表完整成环 思路:使用两个指针,一个每次往前走2步,一 ...

  5. 2013 长沙网络赛 B 题 Bizarre Routine

    题解 http://blog.csdn.net/u010257508/article/details/11936129 #include <iostream> #include <c ...

  6. C++11中正則表達式測试

    VC++2010已经支持regex了, 能够用来编译下述代码. #include <string> #include <regex> #include <iostream ...

  7. ant学习(1)

    路径:/home/framework_Study/springinAction/webRoot/WEB-INF <?xml version="1.0" encoding=&q ...

  8. 远程连接到Fedora

    首先执行以下3点(主要是前两点) 第一: 开启ssh #service sshd restart 第二:关闭防火墙 #service iptables stop 第三:selinux(重启电脑后失效) ...

  9. easyUI的datagrid控件日期列不能正确显示Json格式数据的解决方案

    EasyUI是一套比较轻巧易用的Jquery控件,在使用过程中遇到一个问题,它的列表控件——datagrid, 在显示日期列的时候,由于后台返回给页面的数据是Json格式的,其中的日期字段,在后台是正 ...

  10. 使用 Fluent API 配置/映射属性和类型2

    1.将多个实体类映射到数据库中的一个表 要将多个实体映射到一个数据库表需要满足: a. 两个实体必须是一对一关系 b.两个实体共享一个主键 public class MyContext:DbConte ...