浅谈 xargs 的几个妙用
一直以来,xargs 都被我用作是管道符的连接命令,比如 cat delete.txt|xargs rm -f
,并且一般是在直接管道不可用的情况下,才会想起用 xargs 命令来分行处理。但是今天,在使用 xargs 进行文件批处理的时候,发现了很多 xargs 的小妙用。
替换字符串
xargs -I
将指定一个字符串 {}
,用于代替接受的字符串进行操作,类似于 find -exec
的 {}
。
比如,有10个文件,想要将他们重命名为以 .txt
结尾,可以这么操作:
[asbuser@2B2C-test-DB1 tmp]$ ls
0 1 2 3 4 5 6 7 8 9
[asbuser@2B2C-test-DB1 tmp]$ ls|xargs -I {} mv {} {}.txt
[asbuser@2B2C-test-DB1 tmp]$ ls
0.txt 1.txt 2.txt 3.txt 4.txt 5.txt 6.txt 7.txt 8.txt 9.txt
[asbuser@2B2C-test-DB1 tmp]$
多行输入单行输出
xargs 虽然是分行处理工具,但其默认输出却是单行的:
[asbuser@2B2C-test-DB1 tmp]$ cat 0.txt
123
456
779
000
[asbuser@2B2C-test-DB1 tmp]$ cat 0.txt|xargs
123 456 779 000
[asbuser@2B2C-test-DB1 tmp]$
单行输入多行输出
xargs -n
可指定输出时每行输出多少个参数:
[asbuser@2B2C-test-DB1 tmp]$ cat 1.txt
123 456 789 000
[asbuser@2B2C-test-DB1 tmp]$ cat 1.txt|xargs -n2
123 456
789 000
[asbuser@2B2C-test-DB1 tmp]$
xargs -d
可指定一个定界符,分割参数,和 cut -d
类似:
[asbuser@2B2C-test-DB1 tmp]$ cat 2.txt
123x456x789x000
[asbuser@2B2C-test-DB1 tmp]$ cat 2.txt|xargs -dx
123 456 789 000
[asbuser@2B2C-test-DB1 tmp]$
-n
和 -d
结合使用:
[asbuser@2B2C-test-DB1 tmp]$ cat 2.txt
123x456x789x000
[asbuser@2B2C-test-DB1 tmp]$ cat 2.txt|xargs -dx -n2
123 456
789 000
[asbuser@2B2C-test-DB1 tmp]$
处理带空格的文件名
当文件名包含空格时,作字符分割往往会出错,比如:
[asbuser@2B2C-test-DB1 tmp]$ ls
0 0 0.txt 0.txt 1.txt 2.txt 3.txt 4.txt 5.txt 6.txt 7.txt 8.txt 9.txt
[asbuser@2B2C-test-DB1 tmp]$ ls|xargs -n2
0 0
0.txt 0.txt
1.txt 2.txt
3.txt 4.txt
5.txt 6.txt
7.txt 8.txt
9.txt
[asbuser@2B2C-test-DB1 tmp]$
上面这个命令,将 0 0 0.txt
这个文件名称也给分割了。
为了避免这种情况,我们需要加上 -0
参数,-0
将 \0
作为定界符。
[asbuser@2B2C-test-DB1 tmp]$ ls|xargs -n2
0 0
0.txt 0.txt
1.txt 2.txt
3.txt 4.txt
5.txt 6.txt
7.txt 8.txt
9.txt
[asbuser@2B2C-test-DB1 tmp]$ ls|xargs -0 -n2
0 0 0.txt
0.txt
1.txt
2.txt
3.txt
4.txt
5.txt
6.txt
7.txt
8.txt
9.txt
[asbuser@2B2C-test-DB1 tmp]$
对于此情况,官方也有特别说明:
find /tmp -name core -type f -print | xargs /bin/rm -f
Find files named core in or below the directory /tmp and delete them. Note that
this will work incorrectly if there are any filenames containing newlines or spaces.
find /tmp -name core -type f -print0 | xargs -0 /bin/rm -f
Find files named core in or below the directory /tmp and delete them, processing
filenames in such a way that file or directory names containing spaces or newlines
are correctly handled.