【Linux命令】-xargs
声明:本文框架和思路均参考阮一峰博客的xargs 命令教程
xargs通常用于将A命令的输出作为B命令的输入(参数),因为一些命令的参数无法使用标准输入(stdin)而只能使用命令行
对于那些可以使用stdin作为参数的命令,我们并不需要xargs,直接使用 |
即可
如cat /etc/shells | grep bash
而对于不支持stdin作为参数的命令,我们就不能通过|
来连接,这就是xargs应用的地方了。
下面主要说明这几个参数
- -L & -n,与分块相关
- -p & -t,与用户交互相关
- -d & -0,与分割符相关
- -I,与占位符相关
- --max-procs & -P,与并行执行相关
-L & -n
xargs默认尽可能多的将输入分割成合适大小的块,但有时候传入的参数过多会导致效率下降
注意在
find . -name "*.txt" | xargs grep "abc"
中,由于grep每次只能处理一个文件,故这里会逐个对每个文件进行grep
而在一些可以接收若干参数的命令中,grep就会一次性喂给其多个(在不超过其上线的情况下)
-n与-L则是针对这个问题的一种解决方案:限制每个命令行执行时传递的参数数量,以避免一次处理过多文件提高效率
其中-n是同一行中的多项,而-L则是不同行中的多项
假设file_list_lines.txt中的文件内容如下:
a.txt
b.txt
c.txt
d.txt
cat file_list_lines.txt | xargs -L 2 rm
将file_list_lines.txt中的文件名按每2行为一组传递给rm
假设file_list_line.txt中的文件内容如下:
a.txt b.txt c.txt d.txt
cat file_list_line.txt | xargs -n 2 rm
将file_list_line.txt中的文件名按每两项为一组传递给rm
若file_list_line中有若干行,在mac中依旧可works,暂不清楚linux上
-p & -t
-p在每次执行命令之前询问用户是否继续执行
-t在执行命令之前输出要执行的命令以及要传递给该命令的参数,其主要是帮助用户了解即将执行的命令,但不会询问用户是否确认执行
-d & -0
xargs默认空格、制表符和换行符为分隔符,-d参数则可用来灵活指定分隔符,而-0参数则是指定分隔符为null字符('\0')
-d参数在mac中无法使用(似乎是由于mac上的xargs是BSD版本?)
假设file_list_line.txt中的文件内容如下:
a.txt,b.txt,c.txt,d.txt
cat file_list_line | xargs -d ',' echo
-0参数在处理包含特殊字符(如空格,而xargs默认以空格为分隔符,这就会导致一个文件名在处理时会被分成两个)的文件名时可以确保处理的正确性
-0最常是与find 命令的 -print0 选项一起使用,-print0 会以 null 字符作为分隔符来打印文件名。然后,xargs 使用 -0 选项来指定以 null 字符作为输入的分隔符,从而正确处理包含特殊字符的文件名
-I
指定一个占位符来代表从标准输入流中接收到的参数,一般用来将命令行参数传给多个命令
-I后面紧跟的就是占位符,举个例子
假设files.txt中的文件内容如下:
/home/user/file1.txt
/home/user/file2.txt
/home/user/file3.txt
这里的{}就是占位符,
cat files.txt | xargs -I {} ls -l {}
当然这里也可以用-n来实现
cat files.txt | xargs -n 1 ls -l
另一个例子就像开头那篇博文里那样,利用占位符将参数传给多个命令
cat foo.txt | xargs -I file sh -c 'echo file; mkdir file'
这里使用单引号是为了确保整个命令被作为一个参数传递给 sh -c 命令,防止 shell 在执行之前对其中的特殊字符进行解析和扩展
--max-procs || -P
用于指定同时运行的子进程的最大数量。用于并行执行任务时,尤其是处理大量数据或者需要利用多核处理器,因为xargs命令默认只使用一个进程执行命令
cat files.txt | xargs -P 4 -I {} gzip {}
用四个进程来执行解压,提高效率
另外注意,--max-procs n 表示最多使用n个进程,而--max-procs 0 表示不限制进程数。