对于xargs这个命令了解的不是很多,但是在脚本编写中能起到非常大的作用。
标准的管道
平时我们可以通过管道符将前面的值传递到后面,这样可以完成各种查询等工作,比如下面的例子:
此时我们有一个文件test.txt
,我们要检索出带有hello 的一行。
$ cat test.txt
test data
hello world
write code
$ cat test.txt | grep hello
hello world
此时,通道符是作用的,因为管道符的作用的是将左侧命令的标准输出转换为标准输入,提供给右侧命令作为参数。而grep
命令是可以接受标准输入作为参数的所以此时命令是奏效的。
但是并不是所有命令都能接受标准输入作为参数,大部分命令都是不接受标准输入作为参数的,只能在命令行输入参数,而不能使用管道传递参数,比如说下面的命令
echo "abc" | echo
上面的代码不会输出任何数据,因为echo命令不能接受标准输入作为参数。
xargs命令
2.1 xargs是啥命令
xargs命令是传递参数的一个过滤器,也是组合多个命令的工具。
xargs的作用:
- 可以将管道或者标准输入转换为命令行参数,也可以从文件的输出中读取参数。
- 可以将单行或者多行文本输入转换为其他格式,类似于矩阵变换,例如多行边单行输出,单行变多行输出。
xargs echo
是xargs的默认命令,也就是说单单使用xargs
命令也就等同于xargs echo
,不过通过xargs的处理,输入文本中的换行和空白将会被空格替代。
对于上面一节中无法处理的命令,通过xargs命令就可以简单处理,命令如下所示:
echo "abc" | xrags
# 或者
echo "abc" | xargs echo
2.2 xargs单独使用
大部分时间xargs
都是和管道符一起使用的,但难免也会出现单独使用的时候,如下在终端内直接输入xargs
。
xargs
hello world (ctrl + d)hello world
在终端内只输入xargs
并且按下回车后,命令行就会等待用户输入任何内容,作为标准输入,按下ctrl+d
表示结束,随后xargs
就会把输入的内容在终端内打印出来。
此时我们可以使用xargs的这种特性,和find命令一起使用。
xargs find -name
*.txt(ctrl + d)
*.txt./.pki/nssdb/pkcs11.txt
./.Genymobile/Genymotion/deployed/Google Pixel/logcat.txt
./.Genymobile/Genymotion/deployed/Xiaomi Redmi Note 7/logcat.txt
./.cache/tracker3/files/last-crawl.txt
./.cache/tracker3/files/first-index.txt
./.cache/tracker3/files/locale-for-miner-apps.txt
....
上面的例子输入xargs find -name
以后,命令行会等待用户输入所要搜索的文件。用户输入"*.txt"
,表示搜索当前目录下的所有 TXT 文件,然后按下Ctrl + d
,表示输入结束。这时就相当执行find -name *.txt
。
2.3 xargs的正确使用
xargs命令格式
somecommand | xargs [-options] [command]
xargs的参数,可以通过xargs -h/--help
查看具体帮助
参数 | 作用 |
---|---|
-0, --null | 使用null作为分割符 |
-a, --arg-file=文件 | 从指定<文件>读取参数,不使用标准输入 |
-d, --delimiter=分隔用字符 | 可以指定任意字符串作为分割符 |
-E 终止符, -e, --eof[=终止符] | 设置逻辑 EOF(逻辑文件末尾)字符串;如果<终止符>作为单独一行输入,所有剩余的输入内容将被忽略(若同时使用了 -0 或 -d 选项,则该选项失效) |
-I, -i, --replace[=R] | 可以将标准输入的内容复制到设置的变量中,并用在后续的命令中 |
-l, -L, --max-lines=最大行数 | 每个命令行使用最多<最大行数>行的非空输入行 |
-n, --max-args=最大参数数量 | 设置每个命令行可使用的<最大参数数量> |
-o, --open-tty | 在执行命令之前,在子进程中将stdin重新打开为/dev/tty;对于运行交互式应用程序非常有用。 |
-P, --max-procs=MAX-PROCS | 同时运行至多个进程 |
-p, --interactive | 运行命令前提示 |
–process-slot-var=VAR | 在子进程中设置环境变量 |
-r, --no-run-if-empty | 如果没有指定任何参数,则不运行指定的<命令>; |
如果未给出该选项,指定的<命令>将至少运行一次 | |
-s, --max-chars=最大字符数 | 限制命令行长度的<最大字符数> |
–show-limits | 显示命令行长度的限制 |
-t, --verbose | 执行命令前输出命令内容 |
-x, --exit | 如果大小(见 -s)超出限制则退出 |
–version | 输出xargs版本信息 |
以下介绍常用的一些参数使用方法。
2.3.1 -0,-null
somecommand | xargs -0 command
xargs
命令的-0
参数表示使用null
将标准输入进行分割。
了解-0
参数的作用后,find
命令此时非常适合和该参数一起使用,命令如下所示:
find ~/test_dir -print0 | xargs -0 rm -rf
此时~/test_dir
文件夹中有4个文件夹以及4个txt
文件
上面命令的意思是删除~/test_dir
文件夹中的所有文件,由于find
命令使用了-print0
参数,制定输出的文件列表都是以null
分割的,而xargs -0
也是将null
当分割副,所以分割结果如下:
$ find ~/test_dir/ -print0
/home/xx/test_dir//home/xx/test_dir/4.txt/home/xx/test_dir/4/home/xx/test_dir/3/home/xx/test_dir/2.txt/home/xx/test_dir/2/home/xx/test_dir/1/home/xx/test_dir/3.txt/home/xx/test_dir/1.txt
$ find ~/test_dir/ -print0 | xargs -0
/home/xx/test_dir/ /home/xx/test_dir/4.txt /home/xx/test_dir/4 /home/xx/test_dir/3 /home/xx/test_dir/2.txt /home/xx/test_dir/2 /home/xx/test_dir/1 /home/xx/test_dir/3.txt /home/xx/test_dir/1.txt
xargs
还有一个优点就是可以依次执行每一个参数,而不会让rm
命令产生"参数列表过长的错误"。
2.3.2 -d
somecommand | xargs -d "\t"
xargs
默认是以空格作为分割符,但是-d
参数可以让我们自定义分割符
echo "1.txt 2.txt 3.txt 4.txt" | xargs touch
echo "1.txtb2.txtb3.txtb4.txt" | xargs -d "b"
2.3.3 -E, -e, -eof
somecommand | xargs -E "\n"
xargs
可以使用-E
参数设置字符串终止符,终止符后面的字符串都会被舍弃。
echo "1.txtb2.txtb3.txtb4.txt" | xargs -d "b" | xargs -E "\n"
2.3.4 -I, -i, --replace
somecommand | xargs -i "{}"
xargs
可以使用-i
参数设置标准输入的替换值,以便将变量放在指定的位置输出。
echo "1.txtb2.txtb3.txtb4.txt" | xargs --replace=R echo x R r
2.3.5 -L, --max-lines
somecommand | xargs -l 1
-l
参数用来指定多少行作为一个命令行参数。
echo -e "1.txt\n2.txt\n3.txt\n4.txt" | xargs -L 1
echo -e "1.txt\n2.txt\n3.txt\n4.txt" | xargs -L 2
2.3.6 -n, --max-args
somecommand | xargs -n 1
-n
参数可以把一行中的标准输入,以行为单位输出
echo -e "1.txt 2.txt 3.txt 4.txt" | xargs -n 1
echo -e "1.txt 2.txt 3.txt 4.txt" | xargs -n 2
2.3.7 -P, --max-procs
somecommand | xargs -P 2
-P
参数可以指定命令行运行时的进程,-P 2
表示同时最多使用两个进程,-P 0
表示不限制进程数。
echo -e "1.txt 2.txt 3.txt 4.txt" | xargs -P 2
该参数可以大大提高命令运行速度。