Chinaunix首页 | 论坛 | 博客
  • 博客访问: 1399371
  • 博文数量: 247
  • 博客积分: 10147
  • 博客等级: 上将
  • 技术积分: 2776
  • 用 户 组: 普通用户
  • 注册时间: 2008-01-24 15:18
文章分类

全部博文(247)

文章存档

2013年(11)

2012年(3)

2011年(20)

2010年(35)

2009年(91)

2008年(87)

我的朋友

分类: LINUX

2010-08-05 21:01:57

 

xargs构造一个命令行,该命令行由指定的COMMAND, ARGUMENT以及从标准
输入按顺序读取的参数来组成;并确保读取的参数在长度和数量上符合
xargs选项指定的约束。然后,xargs调用该命令行,并等待执行完成。
如此反复,直到读取到结束条件,或者某次命令行执行返回255.

从标准输入读取的参数必须用空白字符(不在引号中)或者是换行符(未转义)
来分隔。不含双引号和换行符的字符串,可以用双引号来引起来。不含单引号和
换行符的字符串可以用单引号引起来。未引起来的字符可以在前面用\来转义。
COMMAND会执行若干次,直到end-of-file。如果COMMAND要从标准输入读取,会
导致结果未定义。

生成的命令行的长度,就是所有字符串(COMMAND,ARGUMENT)的长度之和(包括
某个字符串的结束符null terminator)。xargs会限制命令行的长度,使得命令行
在执行的时候,其参数和环境不会超过{ARG_MAX}-2048字节。在该约束下,如果
没有指定-n和-s选项,那么默认命令行长度就是至少{LINE_MAX}.

选项
-e[EOFSTR]  用EOFSTR来作为逻辑上的end-of-file字符串。如果没有-E和-e选项,
            那么下划线(_)会被当作默认的EOF字符串。如果给了-e标志,但是
            没有给EOFSTR可选参数,那么EOF功能会被禁用,下划线会按字面处理。
            xargs读取标准输入,直到遇到逻辑EOF或者end-of-file.

-E EOFSTR   对于 /usr/bin/xargs:
            指定EOFSTR作为end-of-file字符串来代替默认的下划线(_)。xargs从
            标准输入读取,直到end-of-file或者遇到EOFSTR。EOFSTR不能为空。
          
            对于 /usr/xpg6/bin/xargs:
            指定EOFSTR作为end-of-file字符串来代替默认的下划线(_)。xargs从
            标准输入读取,直到end-of-file或者遇到EOFSTR。如果EOFSTR为空,
            那么EOFSTR功能禁用,下划线(_)会按字面处理。

-I REPLSTR  插入模式。每从标准输入读取1行,就执行依次COMMAND,并把该整行
            当作单个参数,插入到ARGUMENT中的REPLSTR处。ARGUMENTs中最多能包
            含5个REPLSTR。读取的每行字符串,开始的空白字符都会忽略。构成的
            参数,不能超过255字节。-x选项会伴随-I选项强制自动打开。-I和-i
            选项是互斥的,最后指定的生效。
           
-i[REPLSTR] 该选项与-I是等价的。如果没有指定可选参数REPLSTR,则采用{}.

-L NUMBER   每次从标准输入读取NUMBER行非空的行,就执行1次COMMAND。最后1次
            调用COMMAND时,可能会由于不足NUMBER行剩下而有比较少的参数。
            每行都以换行符结尾,除非该行结尾是空白字符,结尾的空白字符表示
            继续包含下一个非空白行。-L, -l和-n选项是互斥的,最后一个生效。

-l[NUMBER]  该选项与-L等价,默认NUMBER是1,并自动强制打开-x选项。

-n NUMBER   执行COMMAND命令时,尽可能多的从标准输入中读取N个参数。
            * 如果标准输入剩下多于0但不足N行,可能不够N个参数。
            * 命令行长度超过-s选项或者LINE_MAX,那么可能不够N个参数

-p          提示模式。每次执行COMMAND前都提示用户。Trace mode(-t)会自动
            打开,从而输出要执行的命令和提示信息到stderr。从/dev/tty
            读取肯定的答复后,COMMAND会执行;否则本次执行会被忽略。

-s SIZE     执行COMMAND时,尽可能多的读取输入参数,但是长度不能超过SIZE。
            命令行长度小于SIZE的情况:
            * 参数总数超过-n指定的
            * 读入的行数超过-L指定的
            * EOF
           
            如果DESCRIPTION中约束被满足,那么SIZE-{LINE_MAX}之间的值也是
            可以支持的。大于实现支持的值或者超过DESCRIPTION中描述的值不
            应该被当作错误。xargs在支持的范围里用最大值。

-t          Trace Mode。打开跟踪模式,从而每次命令行在执行前都打印到stderr.

-x          如果包含NUMBER个参数或NUMBER行的命令行不符合-s指定的size,就终止。

OPERANDS

COMMAND     要调用的命令名,必须通过PATH环境变量能搜到。如果没有指定COMMAND,
            默认会调用echo。如果COMMAND与shell builtin同名,结果未定义。
ARGUMENT    传递给COMMAND的初始选项或参数


USAGE
COMMAND可以用退出状态255来告诉xargs终止执行,尤其是当COMMAND知道继续在该输入
stream上执行不会成功时。因此,COMMAND在多数情况下要避免255退出值.

输入是按行解析的。空白字符用来分隔参数。如果xargs和find DIR -print之类的命令
一起组合使用,而文件名含有空白字符或者换行符,xargs执行会出错。
一个解决方法是:find调用脚本把文件名用引号引起来后,再传递给xargs。但是由于
xargs的引用规则与shell的引用规则不一致,可能还是会有错误。所以,可以把
引号起来的字符串所有字符前面都加\来转义。

某些实现支持大于{ARG_MAX};xargs产生的命令行长度大于{LINE_MAX}。这对COMMAND
不是问题。如果xargs用来产生文本文件,最好通过-s选项来限制每行的长度。

xargs如果遇到错误,返回127,这样就能区分究竟是调用COMMAND出错,还是COMMAND
执行出错。因为127很少用于返回。

示例
1: 把$1中的文件移动到$2
   example% ls $1 | xargs -I {} -t mv $1{} $2/{}
2: 把小括号中的输出组成1行,写入到日志文件
  example% (logname; date; printf "%s\n" "$0 $*") | xargs >>log
  其实等价于
  example% (logname; date; printf "%s\n" "$0 $*")  >>log
3: 对连续的参数对,执行文件比较操作(假设文件名不含特殊字符)
   example% printf "%s\n" "$*" | xargs -n 2 -x diff
4: 提示用户,把文件打包起来
   每次一个文件
   example% ls | xargs -p -L 1 ar -r arch
   打包多个文件
   example% ls | xargs -p -L 1 | xargs ar -r arch
5. REPLSTR为字节定义的字符串,一般选用{}
> (echo "1" ; echo 2)
1
2
#-I选项导致整行被当作1个参数。
> ( echo "1 a" ; echo 2 ) | xargs -I p echo "heihei" {}
heihei {}
heihei {}
> ( echo "1 a" ; echo 2 ) | xargs -I p echo "heihei" p
heihei 1 a
heihei 2
# p为REPLSTR
> ( echo "1 a" ; echo 2 ) | xargs -I p echo "heihei" p "hello"
heihei 1 a hello
heihei 2 hello
 > ( echo "1 a" ; echo 2 ) | xargs -I p echo "heihei" p "hello" p
heihei 1 a hello 1 a
heihei 2 hello 2
> cat xargs.sh
#!/bin/bash
if [ "$#" == 0 ] ; then
   echo "$0: arg num=0"
else
   echo "argnum=$# $@"
fi
> ( echo "1 a" ; echo 2 ) | xargs -I p ./xargs.sh  "heihei" p                
argnum=2 heihei 1 a
argnum=2 heihei 2
> ( echo "1 a" d e; echo 2 ) | xargs -I p ./xargs.sh "heihei" p
argnum=2 heihei 1 a d e
argnum=2 heihei 2
> ( echo "1 a" d e ; echo 2 ) | xargs -I p ./xargs.sh p "heihei" p
argnum=3 1 a d e heihei 1 a d e
argnum=3 2 heihei 2

# 无-I选项,参数从输入行用空白分隔。
> echo "a b c " | xargs ./xargs.sh -f b
argnum=5 -f b a b c
> echo "a b c c e f g" | xargs -n 5 ./xargs.sh -f b
argnum=7 -f b a b c c e
argnum=4 -f b f g

# -I选项与-n选项貌似不兼容,
# -I在前, -n在后,{}未能识别
> echo "a b c c e f g" | xargs -I {}  -n 5 ./xargs.sh {} -f  b
argnum=8 {} -f b a b c c e
argnum=5 {} -f b f g
# -n在前, -I在后,整行当作参数
> echo "a b c c e f g" | xargs  -n 5 -I {} ./xargs.sh {} -f b
argnum=3 a b c c e f g -f b

注意:
xargs从标准输入中读取数据,并以空白和换行符分割每个参数(引号中的空
白不作为分割符)。然后执行指定的命令(并把分解后的参数附加到命令后面)。
如果没有指定具体的命令,默认使用/bin/echo命令。
如果没有特别指定,xargs会把`_'当作结束标志。
综上所述,xargs不适合用作文本处理,特别是重要的数据处理。

阅读(5585) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~