xargs
- 命令用法
[root@localhost xiangjis]# cat -E text1
11 apple$
12 pear$
13 banana$
[root@localhost xiangjis]# cat text1 | xargs \\此处为空格字符分隔
11 apple 12 pear 13 banana
为了方便看清楚,上图匹配到的红色部分,即为空格
[root@localhost xiangjis]# cat text1 | xargs -t \\默认的执行命令为echo,分隔符为空格,这里用到了-t选项,后边还会有演示
echo 11 apple 12 pear 13 banana
11 apple 12 pear 13 banana
[root@localhost xiangjis]# echo aaa@bbb@ccc | xargs
aaa@bbb@ccc
[root@localhost xiangjis]# echo aaa@bbb@ccc | xargs -d @ \\指定分隔符为@
aaa bbb ccc
[root@localhost xiangjis]#
[root@localhost xiangjis]# xargs < text1 \\以上的参数都通过管道符传递的标准输出,这个是来自标准输入
11 apple 12 pear 13 banana
[root@localhost xiangjis]# xargs -a text1 \\指定参数来自文件
11 apple 12 pear 13 banana
[root@localhost xiangjis]# ls text* | cat \\管道符将ls运行的标准输入当作标准输入传给cat运行
text1
text2
text3
[root@localhost xiangjis]# ls text* | xargs -p cat \\ls运行的标准输出通过xargs运行后,被当作参数传给cat运行
cat text1 text2 text3 ?...yes
11 apple
12 pear
13 banana
21 apple
22 pear
23 banana
31 apple
32 pear
33 banana
以上两个标准输出对比下,唯一的区别是是否通过xargs命令运行,通过xargs运行后,cat输出的结果是文件的内容,而前者仅为文件的名字。前者cat 是将管道前命令的标准输出作为标准输入运行,后者cat将前者的标准输出作为参数运行,而这都是xargs的功劳。
[root@localhost xiangjis]# ls text* | xargs -p cat
cat text1 text2 text3 ?...no
[root@localhost xiangjis]#
[root@localhost xiangjis]# ls text* | xargs -p cat
cat text1 text2 text3 ?...no
[root@localhost xiangjis]# ls text* | xargs -p -n 1 cat \\每次运行的参数数量为1个,默认按照空白字符分割每个命令参数
cat text1 ?...yes
11 apple
12 pear
13 banana
cat text2 ?...no
cat text3 ?...yes
31 apple
32 pear
33 banana
[root@localhost xiangjis]# ls text* | xargs -p -n 2 cat \\每次运行两个参数,因为一共就三个参数,最后运行一个参数
cat text1 text2 ?...yes
11 apple
12 pear
13 banana
21 apple
22 pear
23 banana
cat text3 ?...yes
31 apple
32 pear
33 banana
[root@localhost xiangjis]# ls text* | xargs -p -E text2 cat \\只运行text2之前的参数
cat text1 ?...yes
11 apple
12 pear
13 banana
[root@localhost xiangjis]# ls text* | xargs -p -E text3 cat
cat text1 text2 ?...yes
11 apple
12 pear
13 banana
21 apple
22 pear
23 banana
[root@localhost xiangjis]# ls text* | xargs -t -E text2 cat
cat text1
11 apple
12 pear
13 banana
[root@localhost xiangjis]# ls text* | xargs -t -E text3 cat
cat text1 text2
11 apple
12 pear
13 banana
21 apple
22 pear
23 banana
[root@localhost xiangjis]# cat text1 | xargs
11 apple 12 pear 13 banana
[root@localhost xiangjis]# cat text1 | xargs -n1
11
apple
12
pear
13
banana
[root@localhost xiangjis]# cat text1 | xargs -n2 -t \\每次运行两个参数
echo 11 apple
11 apple
echo 12 pear
12 pear
echo 13 banana
13 banana
[root@localhost xiangjis]# cat text1 | xargs -L2 -t \\将行当作参数,并设定一行两个参数
echo 11 apple 12 pear
11 apple 12 pear
echo 13 banana
13 banana
[root@localhost xiangjis]# pwd
/tmp/mytest/xiangjis
[root@localhost xiangjis]# ls text*
text1 text2 text3
[root@localhost xiangjis]# ls text* | xargs -i -t cp {} .. \-i参数,指定默认替代符为{},该参数已渐渐被-I(大写)取代
cp text1 ..
cp text2 ..
cp text3 ..
[root@localhost xiangjis]# ls ../text*
../text1 ../text2 ../text3
[root@localhost xiangjis]# ls ../text* | xargs -I [] -t rm [] \-I参数,指定[]为替换符
rm ../text1
rm ../text2
rm ../text3
[root@localhost xiangjis]# ls ../text*
ls: 无法访问../text*: 没有那个文件或目录
[root@localhost xiangjis]# xargs -t -I x echo "(x)" < text1 \-I参数,指定x为替换符
echo (11 apple)
(11 apple)
echo (12 pear)
(12 pear)
echo (13 banana)
(13 banana)
[root@localhost xiangjis]# cp text1 'text 11' \\创建文件名包含空白字符的文件(此处为空格字符)
[root@localhost xiangjis]# ll text*
-rw-r--r--. 1 root root 27 9月 10 22:11 text1
-rw-r--r--. 1 root root 27 9月 12 07:57 text 11
-rw-r--r--. 1 root root 27 9月 10 22:11 text2
-rw-r--r--. 1 root root 27 9月 10 22:11 text3
[root@localhost xiangjis]# ls text* | xargs -t grep apple \\xargs默认的分割符为空白字符,所以文件text 11,被认为为两个文件text和11,而这两个文件是不存在的,所以报错
grep apple text1 text 11 text2 text3
text1:11 apple
grep: text: 没有那个文件或目录
grep: 11: 没有那个文件或目录
text2:21 apple
text3:31 apple
[root@localhost xiangjis]# ls --quoting-style=escape text* \\通过此选项对文件名进行转义
text1 text\ 11 text2 text3
[root@localhost xiangjis]# ls --quoting-style=shell text* \\通过此选项对文件名加上引号
text1 'text 11' text2 text3
[root@localhost xiangjis]# ls --quoting-style=shell text* | xargs -t grep apple \\解决方案一
grep apple text1 text 11 text2 text3
text1:11 apple
text 11:11 apple
text2:21 apple
text3:31 apple
[root@localhost xiangjis]# ls --quoting-style=escape text* | xargs -t grep apple
grep apple text1 text 11 text2 text3
text1:11 apple
text 11:11 apple
text2:21 apple
text3:31 apple
[root@localhost xiangjis]# ls text* | tr '\n' '\0' \\tr将文件名之间的换行符转换成空字符
text1text 11text2text3
[root@localhost xiangjis]# ls text* | tr '\n' '\0' | xargs -0 -t grep apple \\解决方案二,此处运用了xargs -0选项
grep apple text1 text 11 text2 text3
text1:11 apple
text 11:11 apple
text2:21 apple
text3:31 apple
[root@localhost xiangjis]# find -name 'text*' -print0 \\find -print0,改变输出的分割符为空字符
./text1./text2./text3./text 11
[root@localhost xiangjis]# find -name 'text*' -print0 | xargs -0 -t grep apple \\解决方案三,此处运用了xargs -0选项
grep apple ./text1 ./text2 ./text3 ./text 11
./text1:11 apple
./text2:21 apple
./text3:31 apple
./text 11:11 apple
[root@localhost xiangjis]# ls text* | xargs -t -I [] grep apple [] \\解决方案四(自创的),这里用到的主要是-I参数,因为其将行当作参数运行,而非空白字符为分隔符,指定[]为替换字符,指定grep运行其的位置也很关键,否则grep命令运行会报错
grep apple text1
11 apple
grep apple text 11
11 apple
grep apple text2
21 apple
grep apple text3
31 apple
[root@localhost xiangjis]# find -name 'text*' -exec grep apple {} \; \\解决方案四,用find 的-exec,这个就不多说了,本次主要说用xargs的解决方案
11 apple
21 apple
31 apple
11 apple
- 总结
最后也可以用find的-exec参数来完成处理动作,但其支持的参数长度是有限的;所以find经常和xargs结合使用。
-
既然说到了find,在这里说下其-exec命令的用法,如下:
必须使用 {} 标记文件名在命令中的位置。它不是自动添加在末尾的
必须使用转义后的分号终止该命令,比如 ;、';' 或 ";" 都行
该命令对每个输入文件执行一次 -
本次演示很多地方只用到了管道符,有些地方到了管道符和xargs;大家也看到其运行的结果是截然不同的,下面就是两者的主要区别:
管道是实现“将前面的标准输出作为后面的标准输入”
xargs是实现“将标准输入作为命令的参数”