xargs 常常被大家忽略的一个命令,对它的一些用法很多人可能不熟悉,其实它是一个功能强大的命令,特别是在结合管道进行批量处理方面
语法
xargs 语法格式如下
xargs [OPTION]... COMMAND
作用
xargs 最重要的作用是以空格或者换行作为分隔符,把标准输入转化成多个命令行参数,在与管道命令结合使用时,就能体现出 xargs 的作用
下面以实例来说明
[root@ecs-centos-7 tmp]# echo "11 22 33" | xargs mkdir
[root@ecs-centos-7 tmp]# ll
总用量 16
drwxr-xr-x 2 root root 4096 1月 20 00:03 11
drwxr-xr-x 2 root root 4096 1月 20 00:03 22
drwxr-xr-x 2 root root 4096 1月 20 00:03 33
上面的例子中, 管道左侧的命令 echo "11 22 33"
的输出作为管道右侧命令 xargs mkdir
的输入, 管道右侧的命令将左侧的输入以空格或者换行为分隔符分成多个命令行的参数
所以 echo "11 22 33" | xargs mkdir
命令等同于下面的三条命令
mkdir 11
mkdir 22
mkdir 33
选项说明
选项 | 说明 |
---|---|
-d | 指定输入参数的分隔符,默认是以空格或换行作为分隔符 |
-p | 打印出将要执行的命令,并询问用户是否要执行 |
-t | 打印出最终执行的命令并执行,不需要用户确认 |
-0 | 表示用 null 作为分隔符 |
-n | 每次将一行中的多少项参数作为命令行参数 |
-I | 指定每一项命令行参数的替代字符串,类似一个存储参数项的中间变量 |
-r | 当输入不包括任何非空格时,不执行命令 |
实例1 不带任何选项的 xargs
xargs 命令大部分是和管道一起使用,但是它也可以单独使用, 这时候xargs相当于 echo 命令,把用户的输入通过echo命令输出到屏幕
[root@ecs-centos-7 ~]# xargs
hello
world
! ( ctrl + d )
hello world !
[root@ecs-centos-7 ~]#
上面的例子中,输入xargs 并回车之后,开始接受用户输入,用户输入 hello world !
后,按 ctrl + d
结束输入,结束之后,屏幕上会输出用户输入的内容
实例2 -d 选项
-d
选项可以指定 xargs 命令的分隔符
[root@ecs-centos-7 ~]# echo -n "a#b#c" | xargs echo
a#b#c
[root@ecs-centos-7 ~]# echo -n "a#b#c" | xargs -d "#" echo
a b c
上面实例中,指定分隔符为 # ,所以 "a#b#c" 就被转换成了 a b c
三个命令行参数了
实例3 -p 选项
-p
选项会打印出将要执行的命令,并且执行命令前做依次是否执行的二次确认,y
表示确认执行,n
表示取消执行
[root@ecs-centos-7 tmp]# echo "a b c" | xargs -p touch
touch a b c ?...y
[root@ecs-centos-7 tmp]# ll
总用量 0
-rw-r--r-- 1 root root 0 1月 20 00:46 a
-rw-r--r-- 1 root root 0 1月 20 00:46 b
-rw-r--r-- 1 root root 0 1月 20 00:46 c
实例4 -t 选项
-t
选项打印出最终执行的命令,并且直接执行命令,不再需要用户二次确认
[root@ecs-centos-7 tmp]# ll
总用量 0
-rw-r--r-- 1 root root 0 1月 20 00:49 a
-rw-r--r-- 1 root root 0 1月 20 00:49 b
-rw-r--r-- 1 root root 0 1月 20 00:49 c
[root@ecs-centos-7 tmp]# echo "a b c" | xargs -t rm
rm a b c
实例5 -0 选项
前面我们讲过 xargs 命令是以空格或换行为分隔符的,大部分情况下执行都是正常的,但是有一种情况下会出现问题,那就是当文件名中包含空格的时候
含有空格的文件名当作输入传给 xargs 的时候,会被 xargs 当作多个命令行参数来处理
下面的例子重现了问题
[tt@ecs-centos-7 tmp]$ ls
a.txt b 1.txt c.txt
[tt@ecs-centos-7 tmp]$ ls | xargs -t rm
rm a.txt b 1.txt c.txt
rm: 无法删除"b": 没有那个文件或目录
rm: 无法删除"1.txt": 没有那个文件或目录
[tt@ecs-centos-7 tmp]$
例子中,通过 ls
命令知道目录下有 a.txtb 1.txtc.txt 三个文件
当通过 ls | xargs -t rm
命令来删除目录下所有文件的时候发现,a.txt 和 c.txt 都能被正确的删除,但是 b 1.txt文件名中包含空格,删除的时候会被当作 b 和 1.txt 两个文件处理
所以,例子中输出结果中才会出现 rm: 无法删除"b": 没有那个文件或目录 和 rm: 无法删除"1.txt": 没有那个文件或目录 的错误提示
上述的问题可以通过 -0
选项结合find
命令来解决
[tt@ecs-centos-7 tmp]$ ls
a.txt b 1.txt c.txt
[tt@ecs-centos-7 tmp]$ find . -type f -print0 | xargs -0 -t rm
rm ./a.txt ./b 1.txt ./c.txt
[tt@ecs-centos-7 tmp]$ ll
总用量 0
[tt@ecs-centos-7 tmp]$
find
命令的 -print0
选项表示输出的文件列表以 null 分隔
同时,xargs
命令的 -0
选项表示以 null 作为分隔符
从输出结果可以看出,-0
选项结合find
命令可以正确的删除包含空格的文件名
实例6 -n 选项
有时用户会输入多个参数,-n
选项是每次将一行中的多少个参数作为命令行参数
[tt@ecs-centos-7 tmp]$ echo "a b c d e f" | xargs -n 2
a b
c d
e f
[tt@ecs-centos-7 tmp]$ echo "a b c d e f" | xargs -n 4
a b c d
e f
[tt@ecs-centos-7 tmp]$
命令 echo "a b c d e f" | xargs -n 2
指定每2个参数作为一次命令的输出,所以 a b c d e f
6个参数输出了3行
同样的,命令 echo "a b c d e f" | xargs -n 4
指定每4个参数作为一次输出,所以 a b c d e f
6个参数输出2行,而且第2行只有两个参数
实例7 -r 选项
此选项表示,当输入不包含非空格时,不执行命令,默认情况下,不管输入是否包含非空格时,都会执行命令
有些命令必须要有操作数,如果输入不包含任何参数时,执行这些命令会有缺少操作数的错误提示,可以加上 -r
选项就不会出现错误提示了
[tt@ecs-centos-7 tmp]$ echo '' | xargs rm
rm: 缺少操作数
Try 'rm --help' for more information.
[tt@ecs-centos-7 tmp]$ echo '' | xargs -r rm
[tt@ecs-centos-7 tmp]$
上面的例子中,命令 echo ''
的结果作为输入传给管道右边的 xargs rm
,经过参数转化,xargs rm
没有任何参数,所以执行 rm
命令时会提示缺少操作数,但是 xargs -r rm
命令是不会执行的,所以它不会有错误提示
实例8 -I 参数
-I
参数表示命令行参数的每一项参数的变量
[tt@ecs-centos-7 tmp]$ ls
a b c
[tt@ecs-centos-7 tmp]$ ls | sort | xargs -I F sh -c 'echo F.txt; touch F.txt'
a.txt
b.txt
c.txt
[tt@ecs-centos-7 tmp]$ ls
a a.txt b b.txt c c.txt
上面例子中,当前目录有 a b c
三个文件
命令 ls | sort | xargs -I F sh -c 'echo F.txt; touch F.txt'
的输入分别是 a、b、c,-I F
表示 F
是输入参数的替代字符串,执行命令的时候,后面命令 echo F.txt; touch F.txt
中的 F
会被实际的参数替换掉,实际会执行下面几条命令
echo a.txt; touch a.txt
echo b.txt; touch b.txt
echo c.txt; touch c.txt
小结
本文介绍了 xargs
命令的常见用法,常用的选项都有实例说明,更多关于 xargs
命令的用法请查阅命令文档