浅谈 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.
消息盒子

# 暂无消息 #

只显示最新10条未读和已读信息