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 后有多个参数时,调整参数位置。例如:
1
|
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
1
2
3
4
5
6
7
|
#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参数遇到空参数则直接退出,不会再执行一次,避免程序执行错误。
1
2
3
4
5
|
#ls |grep Tata
#ls |grep Tata |xargs -t
/bin/echo
#ls |grep Tata |xargs -t -r
|
find -print 和 -print0的区别:
-print 在每一个输出后会添加一个回车换行符,而-print0则不会。
实例:
如果path目录下文件过多就会因为“参数列表过长”而报错无法执行。但改用xargs以后,问题即获解决。
1
|
rm `find /path -type f`
|
本例中xargs将find产生的长串文件列表拆散成多个子串,然后对每个子串调用rm。-print0表示输出以null分隔(-print使用换行);-0表示输入以null分隔。
1
|
find /path -type f -print0 | xargs -
0
rm
|
这样要比如下使用find命令效率高的多。
1
|
find /path -type f -exec rm
'{}'
\;
|
xargs命令应该紧跟在管道操作符之后,它以标准输入作为主要的源数据流,并使用stdin并通过提供命令行参数来执行其他命令,例如:
1
|
command | xargs
|
实例应用1,将多行输入转换为单行输出:
1
2
3
4
|
$ cat example.txt
1
2
3
4
5
6
7
8
|
1
2
|
$ cat example.txt | xargs
1
2
3
4
5
6
7
8
|
实例应用2,将单行输入转换为多行输出:
1
2
3
4
5
|
$ cat example.txt | xargs -n
2
1
2
3
4
5
6
7
8
|
空格是默认的定界符,-n 表示每行显示几个参数
还可以使用-d参数来分隔参数,如下:
1
2
3
4
5
|
$ echo
"splitXhiXamosliXsplit"
| xargs -d
"X"
-n
1
split
hi
amosli
split
|
实例应用3,读取stdin,将格式化参数传递给命令
#定义一个echo命令每次在输出参数后都加上#
1
2
|
$ cat cecho.sh
echo $*
'#'
|
#需求1:输出多个参数
1
2
3
4
5
6
|
$ sh cecho.sh arg1
arg1#
$ sh cecho.sh arg2
arg2#
$ sh cecho.sh arg3
arg3#
|
#需求2:一次性提供所有的命令参数
1
2
|
$ sh cecho.sh arg1 arg2 arg3
arg1 arg1 arg2 arg3#
|
#针对需求1、2,使用xargs代替,先用vi建一个新文件args.txt,如下:
1
2
3
4
|
$ cat args.txt
arg1
arg2
arg3
|
#批量输出参数:
1
2
3
4
|
$ cat args.txt | xargs -n
1
arg1
arg2
arg3
|
1
2
3
|
$ cat args.txt | xargs -n
2
sh cecho.sh
arg1 arg2#
arg3#
|
#一次性输出所有参数:
1
2
|
$ cat args.txt | xargs sh cecho.sh ;
arg1 arg2 arg3#
|
需求3,如何将参数嵌入到固定的命令行中?如下所示:
1
2
3
4
5
6
|
$ 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的解决方案:
1
2
3
4
|
$ 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来分隔输出,如下所示,否则可能会误删文件代码如下:
1
|
$ 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 images.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 {}