xargs是一条Unix和类Unix操作系统的常用命令。它的作用是将参数列表转换成小块分段传递给其他命令,以避免参数列表过长的问题;将多行输入转换为单行 (特殊功效)

xargs  [-0prtx] [-E  eof-str] [-e[eof-str]] [--eof[=eof-str]] [--null]

           [-d delimiter] [--delimiter delimiter]  [-I  replace-str]  [-i[replace-
           str]] [--replace[=replace-str]]   [-l[max-lines]]   [-L   max-lines]
           [--max-lines[=max-lines]] [-n max-args] [--max-args=max-args] [-s  max-
           chars]  [--max-chars=max-chars] [-P max-procs] [--max-procs=max-procs]
           [--interactive]     [--verbose]     [--exit]   [--no-run-if-empty]
           [--arg-file=file]   [--show-limits]   [--version]   [--help]   [command
           [initial-arguments]]


xargs一般是和管道一起使用,选项: 


-p 操作具有可交互性,每次执行comand都交互式提示用户选择

-i  告诉 xargs 可以使用{}代替传递过来的参数, 建议使用-I,其符合POSIX标准

-I  格式: xargs  -I  rep-str  comand  rep-srt             

rep-str 为代替传递给xargs参数, 可以使 {} $ @ 等符号 ,其主要作用是当xargs   command 后有多个参数时,调整参数位置。例如:

find  . -name  "*.txt "  |xargs -I {}  cp {} /tmp

-t  启用命令行输出模式:其先回显要运行的命令,然后执行命令,打印出命令结果,跟踪与调试xargs的利器,也是研究xargs运行原理的好办法;


-r  如果没有要处理的参数传递给xargs,xargs 默认是带空参数运行一次,如果你希望无参数时,停止 xargs,直接退出,使用 -r 选项即可,其可以防止xargs 后面命令带空参数运行报错。


-s size 设置每次构造Command行的长度总大小,包括 command +init-param +传递参数,Size 参数必须是正整数 


-n 控制每次输入的参数个数,参数以空白字符或<newline>换行符分割,-L 和 -n 标志是互相排斥的;最后指定的标志生效。


-L num 参数控制每次输入的行数 ,-l和-L功能一样,不建议使用。


-t  参数,打开调试功能,显示每次所组的命令,在调试中非常有用,可以看出xargs的执行原理


-x 如果有任何 Command 行大于 -s Size 标志指定的字节数,停止运行 xargs 命令,-L -I -n 默认打开-x参数


-E  EOF 指定输入结束符 copy

#cat t.txt  
  tata-hi -fuck - ok  
  fuck _you _ you  
#xargs -a t.txt -E _  
  tata-hi -fuck - ok fuck _you  
#xargs -a t.txt -E -  
  tata-hi -fuck

-r  xargs 默认是空参数comand也要执行一次,如使用-r参数遇到空参数则直接退出,不会再执行一次,避免程序执行错误。

#ls |grep Tata  
#ls |grep Tata |xargs -t   
/bin/echo   
  
#ls |grep Tata |xargs -t -r

find -print 和 -print0的区别:

-print 在每一个输出后会添加一个回车换行符,而-print0则不会。


实例:

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

rm `find /path -type f`

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

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

这样要比如下使用find命令效率高的多。

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

xargs命令应该紧跟在管道操作符之后,它以标准输入作为主要的源数据流,并使用stdin并通过提供命令行参数来执行其他命令,例如:

command | xargs

实例应用1,将多行输入转换为单行输出:

$ cat example.txt 
1 2 3 4 5
6 7
8
$ cat example.txt | xargs 
1 2 3 4 5 6 7 8

实例应用2,将单行输入转换为多行输出:

$ cat example.txt | xargs -n 2
1 2
3 4
5 6
7 8

空格是默认的定界符,-n 表示每行显示几个参数

还可以使用-d参数来分隔参数,如下:

$ echo "splitXhiXamosliXsplit" | xargs -d "X" -n 1
split
hi
amosli
split

实例应用3,读取stdin,将格式化参数传递给命令

#定义一个echo命令每次在输出参数后都加上#

$ cat cecho.sh 
echo $*'#'

#需求1:输出多个参数

$ sh cecho.sh arg1 
arg1#
$ sh cecho.sh arg2 
arg2#
$ sh cecho.sh arg3 
arg3#

#需求2:一次性提供所有的命令参数

$ sh cecho.sh arg1 arg2 arg3
arg1 arg1 arg2 arg3#

#针对需求1、2,使用xargs代替,先用vi建一个新文件args.txt,如下:

$ cat args.txt 
arg1
arg2
arg3

#批量输出参数:

$ cat args.txt | xargs -n 1
arg1
arg2
arg3
$ cat args.txt | xargs -n 2 sh cecho.sh
arg1 arg2#
arg3#

#一次性输出所有参数:

$ cat args.txt | xargs sh cecho.sh ;
arg1 arg2 arg3#

需求3,如何将参数嵌入到固定的命令行中?如下所示:

$ sh cecho.sh -p args1 -1
-p args1 -1#
$ sh cecho.sh -p args2 -1
-p args2 -1#
$ sh cecho.sh -p args3 -1
-p args3 -1#

使用xargs的解决方案:

$ cat args.txt | xargs -I {} sh cecho.sh -p {} -1
-p arg1 -1#
-p arg2 -1#
-p arg3 -1#

#-I {}批定了替换字符串,字符串{}会被从stdin读取到的参数所替换,使用-I时,能循环按要求替换相应的参数

实例应用4,结合find使用xargs

前面已经举过例子,这里要注意的是文件名称定界符要以字符null来分隔输出,如下所示,否则可能会误删文件代码如下:

$ find . -type f -name "*test*.txt" -print0 | xargs -0 rm -f


其他:

  • 假如你有一个文件包含了很多你希望下载的URL, 你能够使用xargs 下载所有链接

    cat url-list.txt | xargs wget –c 

  • 查找所有的jpg 文件,并且压缩它

    find / -name *.jpg -type f -print | xargs tar -cvzf p_w_picpaths.tar.gz

  • 拷贝所有的图片文件到一个外部的硬盘驱动 

    ls *.jpg | xargs -n1 -i cp {} /external-hard-drive/directory

  • args结合sed替换:

    find . -name "*.txt" -print0 | xargs -0 sed -i 's/aaa/bbb/g'

  • xargs结合grep:

    find . -name '*.txt' -type f -print0 |xargs -0 grep -n 'aaa'    #“-n”输出行号

  • cat file |(while read a;do echo $a;done)

    cat file |xargs -I {} cat {}