xargs 命令可以通过管道接受字符串,并将接收到的字符串通过空格分割成许多参数(默认情况下是通过空格分隔),然后将参数传递给其后面的命令,作为后面命令的命令行参数。
示例一:
以 cat 为例:
# echo '--help' | cat
--help
#
# echo '--help' | xargs cat
Usage: cat [OPTION]... [FILE]...
Concatenate FILE(s) to standard output.
With no FILE, or when FILE is -, read standard input.
-A, --show-all equivalent to -vET
-b, --number-nonblank number nonempty output lines, overrides -n
-e equivalent to -vE
-E, --show-ends display $ at end of each line
-n, --number number all output lines
-s, --squeeze-blank suppress repeated empty output lines
-t equivalent to -vT
-T, --show-tabs display TAB characters as ^I
-u (ignored)
-v, --show-nonprinting use ^ and M- notation, except for LFD and TAB
--help display this help and exit
--version output version information and exit
Examples:
cat f - g Output f's contents, then standard input, then g's contents.
cat Copy standard input to standard output.
GNU coreutils online help: <https://www.gnu.org/software/coreutils/>
Full documentation at: <https://www.gnu.org/software/coreutils/cat>
or available locally via: info '(coreutils) cat invocation'
这两个命令中,第 1 个输出的是字符串--help
,也就是将 echo 的内容当做 cat 处理的文件内容,实际上就是 echo 命令的输出通过管道定向到 cat 的输入。然后通过 cat 从其标准输入中读取待处理的文本内容。所以这个命令的输入结果为--help
。
第 2 个命令echo '--help' | xargs cat
等价于cat --help
命令组合。就是 xargs 将其接受的字符串--help 做成 cat 的一个命令参数来运行 cat 命令。
示例二:
批量重名文件夹下的文件:
# touch {1..9}.txt
#
# ls
1.txt 2.txt 3.txt 4.txt 5.txt 6.txt 7.txt 8.txt 9.txt test.tar.gz var
#
# ls | xargs -t -i mv {} {}.bak
mv 1.txt 1.txt.bak
mv 2.txt 2.txt.bak
mv 3.txt 3.txt.bak
mv 4.txt 4.txt.bak
mv 5.txt 5.txt.bak
mv 6.txt 6.txt.bak
mv 7.txt 7.txt.bak
mv 8.txt 8.txt.bak
mv 9.txt 9.txt.bak
xargs -i
:该选项在逻辑上用于接受传递的分批结果。如果不使用-i
,则默认是将分割处理后的结果整体传递到命令的最尾部。但是有时会需要传递到多个为止,不使用-i
就不知道传递到那个位置。例如,重命名备份的时候再每个传递过来的文件名加上扩展名.bak,这需要两个参数位。使用xargs -i
时以大括号{}
作为替换符号,传递的时候看到{}就将被结果替换。可以将{}放在任意需要传递的参数位上,如果多个地方使用{}就实现了多个传递。-t
:该选项表示每次执行 xargs 后面的命令都会先再 stderr 上打印一遍执行的命令过程,然后才正式执行。类似的还有一个-p
选项。使用-p
选项是交互询问式的,只有每次询问的时候输入y
(或yes
)才执行,直接按键是不会执行的。比如:
# touch {1..9}.txt
#
# find . -name "*.txt"
./7.txt
./3.txt
./1.txt
./9.txt
./8.txt
./6.txt
./4.txt
./5.txt
./2.txt
# find . -name "*.txt" | xargs -p rm -rf
rm -rf ./7.txt ./3.txt ./1.txt ./9.txt ./8.txt ./6.txt ./4.txt ./5.txt ./2.txt ?...y
#
# touch {1..9}.txt
#
# find . -name "*.txt" | xargs -i -t rm -rf {}
rm -rf ./7.txt
rm -rf ./3.txt
rm -rf ./1.txt
rm -rf ./9.txt
rm -rf ./8.txt
rm -rf ./6.txt
rm -rf ./4.txt
rm -rf ./5.txt
rm -rf ./2.txt
另外-i
参数还有另外的用途,在删除一些特殊文件时保证完整性:
# touch "one space.log"
#
# ls
'one space.log'
#
# find . -name "*.log"
./one space.log
#
# find . -name "*.log" | xargs -i rm -rf "{}"
示例三:
默认情况下 xargs 将其标准输入中的内容以空白(包括空格、Tab、回车换行等)分割成多个之后当做命令行参数传递给其后面的命令并运行,可以使用-d
参数指定分隔符,例如:
# echo '11@22@33' | xargs -d '@' echo
11 22 33
或者
# echo '11@22@33' | xargs -d '@'
11 22 33
这里通过参数-d
指定了分隔符,所以等价于echo 11 22 33
。相当于给 echo 传递了 3 个参数,分布式 11、22、33。在第二个命令中去掉了echo
,得到的结果跟第一个结果一样,其实 xargs 命令后面不加命令的的话,默认会自动调用 echo 命令。可以通过如下方式验证:
# echo '11@22@33' | xargs -d '@' -t
echo 11 22 33
11 22 33
示例四:
xargs 的分批执行,也就是每次传递几个 xargs 生成的命令行参数给其后面的命令执行:
# ls
1.txt 2.txt 3.txt 4.txt 5.txt 6.txt 7.txt 8.txt 9.txt
#
# ls | xargs -n 3 -t
echo 1.txt 2.txt 3.txt
1.txt 2.txt 3.txt
echo 4.txt 5.txt 6.txt
4.txt 5.txt 6.txt
echo 7.txt 8.txt 9.txt
7.txt 8.txt 9.txt
使用-n
可以指定一次传递给 xargs 后面的命令几个参数。
评论