2015-08-29 创建

1、概述

    从标准输入中创建并且执行命令行。

    xargs 从标准输入中读取条目,使用空格(这样可以保护单双引号或者反斜杠)或者换行符分隔,并且执行(默认是 /bin/echo)这些命令。空白行被忽略不执行。

2、命令格式

    xargs  [-0prtx] [-E eof-str] [-e[eof-str]] [--eof[=eof-str]] [--null] [-d delimiter] [--delimiter delimiter] [-I replace-str] [-i[replace-str]]
       [--replace[=replace-str]]  [-l[max-lines]]  [-L  max-lines]  [--max-lines[=max-lines]]  [-n  max-args]  [--max-args=max-args]  [-s   max-chars]
       [--max-chars=max-chars]  [-P  max-procs]  [--max-procs=max-procs]  [--interactive]  [--verbose]  [--exit] [--no-run-if-empty] [--arg-file=file]
       [--show-limits] [--version] [--help] [command [initial-arguments]]


3、常用命令参数

  -a file, --arg-file=file    从file中读取条目信息而不是标准输入。如果你使用该选项,执行命令时标准输入保持不变。否则标准输入被重定向到 /dev/null。

[root@mode-6 ~]# cat test
zhangliang
woshi shui
hgwoeghwie
123123123
ppppp
[root@mode-6 ~]# xargs -a test
zhangliang woshi shui hgwoeghwie 123123123 ppppp

  -0, --null    输入条目被一个 null 字符终止而不是空白字符【也就是输入条目怎样分隔】,并且引号和反斜线不再是特殊字符(每个字符都为他本身,不再赋予特殊意义)。

    禁止文件字符的结尾处像其他参数一样被处理。当输入条目中有 空格,引号,或反斜杠 时是有用的。GNU 的 find -print0 选项生成适合这种的模式输入。示例如下

    find /tmp -name core -type f -print0 | xargs -0 /bin/rm -f    【推介使用】在目录 /tmp 下【包括他的子目录】查找文件名为 core 的文件并删除。即使文件名包含换行符,单引号、双引号,空格;用这个方法也能正确处理。-name 在 -type 之前是为了避免查询的每个文件都去调用 stat(2) 命令

[oldboy@moban oldboy]$ ll  
total 4  
-rw-rw-r-- 1 oldboy oldboy    0 Aug 20 19:25 aa bb  
-rw-rw-r-- 1 oldboy oldboy    0 Aug 20 19:29 ab"db  
-rw-rw-r-- 1 oldboy oldboy    0 Aug 20 19:29 ab'rrr'  
drwxrwxr-x 2 oldboy oldboy 4096 Aug 16 08:57 dir  
[oldboy@moban oldboy]$ find ./ -name 'a*'   
./ab'rrr'  
./ab"db  
./aa bb  
[oldboy@moban oldboy]$ find ./ -name 'a*' -print0       # 没有换行  
./ab'rrr'./ab"db./aa bb  
[oldboy@moban oldboy]$ find ./ -name 'a*' -print0 | xargs -0 /bin/rm -f     # 请记住格式 xargs -0 是数字零不是字母o 或 O  
[oldboy@moban oldboy]$ ll  
total 4  
drwxrwxr-x 2 oldboy oldboy 4096 Aug 16 08:57 dir  

  -d delim, --delimiter=delim    自定义输入条目分隔符。引号,反斜线不在特殊,每个字符都表示他原本的意思。不支持多字节字符

[oldboy@moban xargs]$ find ./ | xargs -I 'test1' 'aa1'
xargs: aa1: No such file or directory
[oldboy@moban xargs]$ echo "splitXhiXamosliXsplit" | xargs -d "X" -n 1
split
hi
amosli
split

[oldboy@moban xargs]$ 

  -E eof-str    设置文件字符串的结尾【读取得到结尾后,如果后面还有内容也不会被读取】。如果输入的一行是文件字符串的结尾,那么该行将被忽略。如果-E 和 -e 都没有被使用,那么没有文件字符串结尾被使用。

[oldboy@moban xargs]$ cat test1           
ls -l /etc/
1231244/
123124
12412412r32
afwefweg/
/
werweer mm

erewr/
[oldboy@moban xargs]$ xargs -a test1 -E 'mm'
ls -l /etc/ 1231244/ 123124 12412412r32 afwefweg/ / werweer
[oldboy@moban xargs]$ xargs -a test1 -E '/' 
ls -l /etc/ 1231244/ 123124 12412412r32 afwefweg/
[oldboy@moban xargs]$ xargs -a test1 -E 'g/'  # 没有找到匹配的 结尾
ls -l /etc/ 1231244/ 123124 12412412r32 afwefweg/ / werweer mm erewr/
  -e[eof-str], --eof[=eof-str]    该选项和 -E 意义相同。 请使用 -E 替代,因为 他的兼容性更好

  -I replace-str    将标准输入的初始化参数名称替换为 replace-str。同时不带引号的空白也不会终止输入条目;相反分隔符是换行字符。意味着 -x 和 -L 1。

[oldboy@moban xargs]$ ll
total 8
drwxrwxr-x 2 oldboy oldboy 4096 Aug 29 15:12 aaaa
-rw-rw-r-- 1 oldboy oldboy   71 Aug 29 12:54 test1
-rw-rw-r-- 1 oldboy oldboy    0 Aug 29 15:12 test2
[oldboy@moban xargs]$ ll | xargs -I hhh echo hhh_123   # 注意用法
total 8_123
drwxrwxr-x 2 oldboy oldboy 4096 Aug 29 15:12 aaaa_123
-rw-rw-r-- 1 oldboy oldboy   71 Aug 29 12:54 test1_123
-rw-rw-r-- 1 oldboy oldboy    0 Aug 29 15:12 test2_123
[oldboy@moban xargs]$ ll | xargs -I{} echo {}      # 注意用法
total 8
drwxrwxr-x 2 oldboy oldboy 4096 Aug 29 15:12 aaaa
-rw-rw-r-- 1 oldboy oldboy   71 Aug 29 12:54 test1
-rw-rw-r-- 1 oldboy oldboy    0 Aug 29 15:12 test2
[oldboy@moban xargs]$ ll | xargs -I[] echo []     # 注意用法
total 8
drwxrwxr-x 2 oldboy oldboy 4096 Aug 29 15:12 aaaa
-rw-rw-r-- 1 oldboy oldboy   71 Aug 29 12:54 test1
-rw-rw-r-- 1 oldboy oldboy    0 Aug 29 15:12 test2
  -i[replace-str],  --replace[=replace-str]    该选项和 -I replace-str 同义,当 replace-str 被指定,并且为 -I{} 时。 该选项已过时,请使用 -I 替代
   -L max-lines    每次最多执行 max-lines 条非空白输入行。 尾随空白导致在下一个输入行上继续输入。意味住 -x

[oldboy@moban xargs]$ ll | xargs  echo 
total 8 drwxrwxr-x 2 oldboy oldboy 4096 Aug 29 15:12 aaaa -rw-rw-r-- 1 oldboy oldboy 71 Aug 29 12:54 test1 -rw-rw-r-- 1 oldboy oldboy 0 Aug 29 15:12 test2
[oldboy@moban xargs]$ ll | xargs -L 1 echo    # 注意用法
total 8
drwxrwxr-x 2 oldboy oldboy 4096 Aug 29 15:12 aaaa
-rw-rw-r-- 1 oldboy oldboy 71 Aug 29 12:54 test1
-rw-rw-r-- 1 oldboy oldboy 0 Aug 29 15:12 test2
  -l[max-lines],  --max-lines[=max-lines]    和 -L 选项同义。不像 -L,max-lines 参数是可选的,而不是必须给定。如果没有指定 max-lines, 那么默认为 1。自从POSIX标准规定 -L 替代后, -l 选项就已经过时了

  -n max-args, --max-args=max-args    每行命令行最多有 max-args 参数。它可以指定一次向目标命令提供几个参数,如果参数数量多于你制定的数量,则命令将会被重复调用,直到所有输入都已经得到执行。注意,最后一次调用的参数有可能会少于指定的参数数量。

[oldboy@moban xargs]$ ll | xargs -l1 echo 
total 8
drwxrwxr-x 2 oldboy oldboy 4096 Aug 29 15:12 aaaa
-rw-rw-r-- 1 oldboy oldboy 71 Aug 29 12:54 test1
-rw-rw-r-- 1 oldboy oldboy 0 Aug 29 15:12 test2
[oldboy@moban xargs]$ ll | xargs -n 2 echo   # 很形象的说明了问题
total 8
drwxrwxr-x 2
oldboy oldboy
4096 Aug
29 15:12
aaaa -rw-rw-r--
1 oldboy
oldboy 71
Aug 29
12:54 test1
-rw-rw-r-- 1
oldboy oldboy
0 Aug
29 15:12
test2
  -p, --interactive    提示用户是否执行该行命令并且该命令从控制台读取。只有'y' 或 'Y' 才会执行该行命令。意味着 -t。

[oldboy@moban xargs]$ ll | xargs  -I{} echo {}  
total 8
drwxrwxr-x 2 oldboy oldboy 4096 Aug 29 15:12 aaaa
-rw-rw-r-- 1 oldboy oldboy   71 Aug 29 12:54 test1
-rw-rw-r-- 1 oldboy oldboy    0 Aug 29 15:12 test2
[oldboy@moban xargs]$ ll | xargs -p -I{} echo {}
echo total 8 ?...y   # 输入 y
echo drwxrwxr-x 2 oldboy oldboy 4096 Aug 29 15:12 aaaa ?...total 8
y      # 输入 y
echo -rw-rw-r-- 1 oldboy oldboy   71 Aug 29 12:54 test1 ?...drwxrwxr-x 2 oldboy oldboy 4096 Aug 29 15:12 aaaa
y      # 输入 y
echo -rw-rw-r-- 1 oldboy oldboy    0 Aug 29 15:12 test2 ?...-rw-rw-r-- 1 oldboy oldboy   71 Aug 29 12:54 test1
y      # 输入 y
-rw-rw-r-- 1 oldboy oldboy    0 Aug 29 15:12 test2
  -r,  --no-run-if-empty    如果标准输入不包含任何空格,那不不执行。通常,命令将会执行一次尽管没有任何输入。这个选项是一个GNU扩展。
  -s max-chars, --max-chars=max-chars    每次命令行的最多字符 max-chars,包括命令、初始参数和在参数字符串结尾的终止符号。

  -t, --verbose    在执行该命令行之前,在标准错误输出上打印命令行。

  -P max-procs, --max-procs=max-procs    同一时间跑  max-procs 个线程;默认是 1.如果  max-procs 是 0,xargs 在同一时间会尽可能多的启动线程。将 -n 和 -P 一起使用;否则,很有可能只有一个线程去做。

4、常用示例

来源于文档:

  find /tmp -name core -type f -print | xargs /bin/rm -f

    在目录/tmp 及其子目录中查找文件名为 core、 文件类型为 f 的文件,并且删除他们。注意:如果这些文件中任一文件名包含换行和空格,那么执行不正确【结果不正确或者报错】。

  find /tmp -name core -type f -print0 | xargs -0 /bin/rm -f   【推介使用】

    在目录/tmp 及其子目录中查找文件名为 core、 文件类型为 f 的文件,并且删除他们。执行过程中文件名或者他的目录名包含换行或空格也将会被正确处理。

  find /tmp -depth -name core -type f -delete

    在目录/tmp 及其子目录中查找文件名为 core、 文件类型为 f 的文件,并且删除他们。但是比之前的例子更有效(因为我们避免了使用 fork(2) 和 exec(2) 去启动rm并且我们不需要额外的 xargs 进程)。

  cut -d: -f1 < /etc/passwd | sort | xargs echo

    在系统中生成所有用户的紧凑列表。

  

5、命令所在位置和类型

[oldboy@moban xargs]$ which xargs
/usr/bin/xargs
[oldboy@moban xargs]$ type xargs
xargs is hashed (/usr/bin/xargs)

6、另请参考

1、linux shell命令之 xargs

2、linux shell脚本学习xargs命令使用详解


Logo

更多推荐