Linux那点事-xargs命令详解

Linux那点事-xargs命令详解

2023年7月26日发(作者:)

Linux那点事-xargs命令详解1. 为什么需要xargs命令1.1 管道|的缺陷管道实现的是将前⾯的输出stdout作为后⾯的输⼊stdin,但是有些命令不接受管道的传递⽅式。例如:ls,这是为什么呢?因为有些命令希望管道传递过来的是参数,但是直接使⽤管道有时⽆法传递到命令的参数位。这时候就需要xargs,xargs实现的是将管道传递过来的stdin进⾏处理然后传递到命令的参数位置上。⽤户查找⽂件:

⽤户希望处理查找后的⽂件:

管道的缺陷也就是xargs完成了两个⾏为:1. 处理管道传输过来的stdin; 2. 将处理后的数据传递到正确的位置;1.2 xargs对数据的处理处理⼤量数据的时候,可能会发⽣参数列表过长的情况。⽽xargs将完成参数的定位我们清楚,但是xrags如何处理管道传输的stdin呢?其实就是完成两个操作:1. 对数据的分割; 2. 对数据的分批;xargs处理的优先级或顺序:先分割,在分批,然后传递到参数位。可以设想⼀个场景,我想对⼀堆数据进⾏处理,实际上是对⼀堆中的每个数据进⾏分别的处理。那么如何将⼀堆数据按照⾃定义规则分割为独⽴的数据?若是⼀次性传递的数据过多,⼜该如何处理?1.2.1 xrags的并发处理但需要注意的是,尽管实现了分批处理,但是默认情况下并没有提⾼任何效率,因为分批传递之后还是⼀次执⾏⼀个。⽽且有时候分批之后是将其作为⼀个参数的整体,并不会将分批中的信息分段执⾏。但事实上,xargs提供了-P选项,⽤于指定并发执⾏的数量(默认是只要⼀个处理进程,不会提供效率,但是可以指定为N个⼦进程,或者指定为0表⽰尽可能多的利⽤CPU)。这样就能将让分批操作更好的利⽤多核CPU,从⽽提升效率。例如上⾯分成了两批,指定-P 2可以并发执⾏两批,⽽并⾮执⾏完第⼀批之后再执⾏第⼆批。剩下的功能就是处理xargs的细节问题了,⽐如如何分割(xargs、xargs -d、xargs -0),分割后如何划批(xargs -n、xargs -L),参数如何传递(xargs -i)。另外xargs还提供了询问交互处理(-p选项)和预先打印⼀遍命令执⾏情况(-t选项),传递终⽌符(-E选项)等。1.2.2 执⾏命令准备命令准备:[root@xuexi tmp]$ cd /tmp[root@xuexi tmp]$ rm -fr *[root@xuexi tmp]$ mkdir a b c d test logdir shdir[root@xuexi tmp]$ touch "one "[root@xuexi tmp]$ touch logdir/{1..10}.log[root@xuexi tmp]$ touch shdir/{1..5}.sh[root@xuexi tmp]$ echo "the second sh the second line" > shdir/

[root@xuexi tmp]$ cat <shdir/

> the first sh> the second line> eof1.2.3 Linux空格含义那么按照什么规则进⾏“分割”以及“分批”呢?Linux⽂件空格分类(重点):

换⾏符、制表符、空格符正⽅形(t)代表:(标记意义)制表符;圆形(空格)代表:(⽂本意义)普通空格;长⽅形(n)代表:(标记意义)换⾏符;

⽂本意义换⾏符和标记意义换⾏符椭圆形代表:(⽂本意义)换⾏符;长⽅形代表:(标记意义)换⾏符;2. xrags的分割⾏为xargs命令会将接收的stdin所有的空⽩(空格、制表符、换⾏符)都转换为空格。我们使⽤xargs -d "xx"⾃定义规则对数据进⾏切分。默认情况下,xargs使⽤空格来切分数据。注意事项xargs -d可以指定分割符,可以是单个符号、字母或者数字。如指定o为分割符:xargs -d "o";xargs -d是分割阶段的选项,所以会优先于分批选项(-n、-L、-i)xargs -d不是先xargs在-d处理的,它是区别于独⽴的xargs的另外⼀个分割选项。1. xargs -d原理替换:将接收stdin所有的【标记意义】的符号替换为n,替换完成后所有的符号(空格、制表符、分⾏符)变成【⽂本意义】上的普通符号。分段:根据-d指定的分隔符进⾏分段,并⽤空格分开每段,由于发⽣了【替换】操作,所以符号都是【⽂本意义】上的。会导致分段中可能包含了空格、制表符、分⾏符。也就是说处了-d导致的【分段空格】,其余所有符号都是分段中的⼀部分。输出:最后根据指定的【分批选项】来输出。2. 案例分析默认情况下,使⽤空格进⾏分割,但若是指定⾃定义分割符(此处使⽤o),那么将o替换为分段空格后,切分独⽴整体。使⽤-d分段xargs -d "o"进⾏⾃定义分割后,然后分批,我们可以看到,实际上分成了2批。

使⽤-n查看-d的分批情况3. xrags -0命令xargs -0的⾏为和xargs -d基本⼀样,只是-d是指定分割符,-0是指定固定的0作为分割符。等价于xargs -d "0"。(注意)xargs -0 可以处理接收到的stdin中的null字符(0)。如果不使⽤-0选项或-null选项,检测到0后会给出警告提醒,并只向命令传递⾮0段。【tr命令:替换或者删除字符】 0的作⽤4. 实际应⽤:【起因】使⽤find+rm命令⽆法删除带有空格的⽂件。

xargs命令输出【原因】:xargs默认是以空⽩字符(空格、换⾏符、制表符)来分割记录的,实际上rm删除的数据便是./one和。⽽【解决⽅案】:此时我们不能使⽤默认的分割符,⽽应该使⽤⾃定义的分割符!我们知道find命令,⽂件后⾯均是换⾏符。

find命令【解决⽅案】为了解决这个问题,可以在每个⽂件将换⾏符替换为NULL(0)。这样我们以0分割,就可以得到完整⽂件。

xargs -0分段为什么要使⽤0作为分割符,⽽不是其他字符呢?因为在编程语⾔中,⼀般使⽤0作为结束标志。⽽⽂件的路径名不可能包含0。本质上是借助xargs的对0的分割操作。find命令将换⾏符替换成0。3. xargs的分批⾏为对于xargs,不写命令时默认的执⾏是echo。

默认xargs命令将换⾏处理掉了将换⾏处理掉不是echo实现的,⽽是管道传递过来的stdin经过xargs处理后得到的。将所有【⽂本/标记意义】空格、制表符和分⾏符都替换为【⽂本意义】上空格并压缩到⼀⾏显⽰。【注意】这⼀整⾏将作为⼀个整体。这个整体可能直接交给命令或者作为stdout通过管道传递给管道右边的命令,这时结果将作为⼀个整体传递,也有可能被xargs同时指定的【分批选项】分批处理。(这也是可能出现参数列表过长的原因)xargs分批命令总结:xargs -n :和独⽴的xargs命令配合使⽤时,按照默认分割符(空格)进⾏分批,但配合xargs -d命令,则按⾃定义分割符分批。xargs -L和-n选项类似,唯⼀的区别就是-L永远是按段划批,⽽-n和独⽴的xargs⼀起使⽤时是按空格分段划批的。2. 对独⽴的xargs指定分批选项【标记/⽂本】指定-n时按空格分段,然后划批,不管是⽂本意义空格还是标记意义的空格,只要是空格都是-n的操作对象。【标记】指定-L或者-i时按段划批,⽂本意义的符号不被处理。【需要注意的是】:【xargs -n】本质上分为两种情况:1. 和独⽴的xargs⼀起使⽤,这时按照每个空格分段划批;2. 和xargs -d或xargs -0⼀起使⽤,这时按段分批;3.

xargs -L和-n选项类似,唯⼀的区别就是-L永远是按段划批,⽽-n和独⽴的xargs⼀起使⽤时是按空格分段划批的。

-n和-L的区别 -i也不会分割⽂本意义的空格4 xargs -i 接收传递的分批结果xargs -i选项在逻辑上⽤于接收传递的分批结果。如果不使⽤-i,则默认是将分割处理后的结果整体传递到【命令的最尾部】。但是有时候需要传递到多个位置,不使⽤-i就不知道传递到哪个位置了。例如:重命名备份的时候在每个传递过来的⽂件名加上后缀.bak,这需要两个参数位。语法: 使⽤xargs -i时以⼤括号{}作为替换符号,传递的时候看到{}就将结果替换,可以将{}放在任意需要传递的参数位置上。如果多个地⽅使⽤{}就实现了多个传递。xargs -I和xargs -i是⼀样的,只是-i默认使⽤⼤括号作为替换符号,-I可以指定其他符号、字母、数字作为替换符号,但是必须⽤引号包起来。man推荐使⽤-I代替-i,但是⼀般使⽤-i⽅便,除⾮在命令中不能使⽤{},例如touch {1...10}.log时,⼤括号就不能⽤来做替换符号。分析:重命名备份的时候在每个传递过来的⽂件名加上后缀.bak。案例分析1:【./指的是当前⽬录】1. 重命名逻辑是:mv ./logdir/ ./logdir/2. 我们想将⼀个⽬录下的⽂件都要执⾏某些逻辑。命令:ls logdir/ | xargs -i mv ./logdir/{} ./logdir/{}.bak为什么将“-i”选项划分在分批选项⾥⾯,因为它默认⼀个段就是⼀个批,每次传递⼀个批就是传递⼀个段到指定⼤括号{}位上。不理解,可以看下1.2.4 分批选项的⽣效规则

xargs的-i字段的使⽤案例分析2:例如:想将数字1-10没三个数显⽰在start和end之间。start 1 2 3 end

start 4 5 6 end

start 7 8 9 end

start 10 end

由于指定了参数传递位置,所以必须使⽤-i,那就⽆法⼀次传递3个数,要解决这个问题,就要想办法让每三个树分⼀次段,然后后使⽤-i传递,那么可以将每三个数分⼀次⾏写⼊⼀个⽂件。例如:

xargs -i分段操作

当然,也可以多次使⽤xargs。在很多使⽤⽆法解决分段的问题都可以通过多次使⽤xargs来解决。

多次使⽤xargs命令进⾏分段5. 分批选项的⽣效规则-i、-L、-n选项都是分批选项,他们的⽣效规则是:谁指定在后⾯,谁就⽣效

-i在-n之后,-n将被忽略实际上,-i就是隐含了-L 1,-i是分批并传递这两个作⽤跟严格些。6. xargs观察命令的执⾏过程使⽤-p选项是交互询问式的,只有每次询问的时候输⼊y(或者yes)才会执⾏,直接按entry键是不会执⾏的。使⽤-t选项是在每次执⾏xargs后⾯的命令都会先在stderr上打印⼀遍命令的执⾏过程然后才正式执⾏。使⽤-p和-t选项就可以根据xargs后⾯的命令的执⾏顺序进⾏推测,xargs是如何分段,分批以及传递的。

-p或者-t参数如何使⽤【后续】 分批选项的的典型应⽤1. 同⼀⽬录下⽂件过多分批选项有时特别有⽤,例如脚本规定每次只能传递三个参数,有时候grep或者rm -rf⽂件数量特别多的时候会提⽰参数列表过长⽽导致失败,这时候就可以分批来按批查询或删除。命令:ls | xargs -n 10000 rm -rf2. xargs+find的使⽤xargs原本就是为find⽽开发的。find命令将匹配到的⽂件传递给xargs命令,⽽xargs命令每次只获取⼀部分⽽不是全部。不像-exec选项那样,这样就可以先处理最先获取的⼀部分⽂件,然后是下⼀批。实际应⽤:ls+grep跨⽬录查询时,我们将⽂件通过管道输⼊到grep参数处,此时并没有包含⽬录地址,边会出现下⾯的错误。

ls + grep 跨⽬录查询解决⽅案:将find找到的⽂件地址传递给grep命令的参数处。

find+grep

发布者:admin,转转请注明出处:http://www.yc00.com/xiaochengxu/1690362238a337945.html

相关推荐

发表回复

评论列表(0条)

  • 暂无评论

联系我们

400-800-8888

在线咨询: QQ交谈

邮件:admin@example.com

工作时间:周一至周五,9:30-18:30,节假日休息

关注微信