目录

xargs命令介绍

xargs命令的作用,是将标准输入转为命令行参数,相当于把别的命令输出的内容,再转为另一个命令的参数,通常用管道符来传递。

基本格式

1
xargs [-options] [command]

ls *.c | xargs grep main xargs紧跟在|后面

常用例子

1
echo /home/aaronkilik/test/ /home/aaronkilik/tmp | xargs -n 1 cp -v /home/aaronkilik/bin/sys_info.sh
  1. -n 1 - 告诉xrgs命令每个命令行最多使用一个参数,并发送到cp命名中
  2. cp - 用于复制
  3. -v - 启用详细模式来显示更多复制细节

复制多个文件到指定目录,cp只能接一个参数

1
cp /home/usr/dir/{file1,file2,file3,file4} /home/usr/destination/

复制不同的文件到指定目录,使用ls找到文件再传递给xargs

1
ls test? | xargs -i cp -r {} wp-rocket
1
echo -e "test1\ntest2" | xargs -I file cp file test3

使用 -I 的时候,命令以循环的方式执行。如果有3个参数,那么命令就会连同 file 一起被执行3次。 file 会在每次执行中被替换为相应的参数。

  1. -I - 表示将前面的参数转为file给cp使用
  2. 使用echo时要用-e进行换行否则不能使用cp
1
2
echo -e "test5\ntest6" | xargs -n 1 -I file cp file wp-rocket
echo {0..9} | xargs -n 2 echo
  1. -n - 表示指定多个项作为参数,-L参数虽然解决了多行的问题,但是有时用户会在同一行输入多项。
  2. -L - 表示指定多个行作为参数,如find命令查出文件为多行,那么通常把每一个作为一个参数来传递,使用 -L 1

查找之后移动所有到指定目录

1
find docxs/ -type f -name "*.docx" -print0 | xargs -0 -n1 -I file  mv file all/

-print0 不会误删文件,指定以 ‘\0’作为分隔符。如果不加print0,文件名中有空格的话,例如 ’test 1.txt’就会被识别为test和1.txt

查找并删除所有的.txt文件:

1
find . -type f -name "*.txt" -print0 | xargs -0 rm -f

-d 选项指定定界符

1
2
echo "splitXabcwerjkX123X5tgb" | xargs -d X
# 输出:split abcwerjk 123 5tgb

多行转为一行

1
2
3
4
5
6
7
8
9
$ cat example.txt
1123
daewr
fwer
sdf
ew34

$ cat example.txt  | xargs
1123 daewr fwer sdf ew34

单行转为多行

1
2
3
4
5
6
7
8
9
$ cat example.txt  | xargs
ew34 32432 bade febte

# -n 指定每行多少个参数
$ cat example.txt  | xargs -n 1
ew34
32432
bade
febte

工作原理 xargs命令接受来自stdin的输入,将数据解析成单个元素,然后调用指定命令并将这些元素作为该命令的参数。xargs 默认使用空白字符分割输入并执行 /bin/echo

与 find 结合,文件名中包含空格的处理

find /smbMount -iname '*.docx' -print0 | xargs -0 grep -L image

xargs 与 子shell,可以实现给多个命令传递参数

1
2
$ cat files.txt | ( while read arg; do cat $arg; done )
# 等同于cat files.txt | xargs -I {} cat {}

find . -name '*.c' | xargs -I ^ bash -c "echo -ne '\n ^: '; grep main ^"

-c string:命令从-c后的字符串读取

子shell中包含for的例子

1
2
$ mkdir ~/backups
$ find /path -type f -name '*~' -print0 | xargs -0 sh -c 'for filename; do cp -a "$filename" ~/backups; done' sh

最后没有sh没有效,尝试使用其他命令也可以生效,好像是随便加什么都可以

参考资料

参考链接