我们可以用管道将一个命令的stdout(标准输出)重定向到另一个命令的stdin(标准输入)。例如:

cat foo.txt | grep "test"

但是,有些命令只能以命令行参数的形式接受数据,而无法通过stdin接受数据流。在这种情况下,我们没法用管道来提供那些只有通过命令行参数才能提供的数据。

那就只能另辟蹊径了。该xargs命令出场了,它擅长将标准输入数据转换成命令行参数。xargs能够处理stdin并将其转换为特定命令的命令行参数。xargs也可以将单行或多行文本输入转换成其他格式,例如单行变多行或是多行变单行。

Bash用户都爱单行命令。单行命令是一个命令序列,各命令之间不使用分号,而是使用管道操作符进行连接。精心编写的单行命令可以更高效、更简捷地完成任务。就文本处理而言,需要具备扎实的理论知识和实践经验才能够写出适合的单行命令解决方案。xargs就是构建单行命令的重要组件之一。

2.5.1 预备知识

xargs命令应该紧跟在管道操作符之后,以标准输入作为主要的源数据流。它使用stdin并通过提供命令行参数来执行其他命令。例如:

command | xargs

2.5.2 实战演练

使用技巧。xargs命令把从stdin接收到的数据重新格式化,再将其作为参数提供给其他命令。

xargs可以作为一种替代,其作用类似于find命令中的-exec。下面是各种xargs命令的

  • 将多行输入转换成单行输出。

    只需要将换行符移除,再用" "(空格)进行代替,就可以实现多行输入的转换。'\n'被解释成一个换行符,换行符其实就是多行文本之间的定界符。利用xargs,我们可以用空格替换掉换行符,这样就能够将多行文本转换成单行文本:

    $ cat example.txt # 样例文件
    1 2 3 4 5 6
    7 8 9 10
    11 12$ cat example.txt | xargs
    1 2 3 4 5 6 7 8 9 10 11 12
    
  • 将单行输入转换成多行输出。

    指定每行最大的参数数量n,我们可以将任何来自stdin的文本划分成多行,每行n个参数。每一个参数都是由" "(空格)隔开的字符串。空格是默认的定界符。下面的方法可以将单行划分成多行:

    $ cat example.txt | xargs -n 3
    1 2 3
    4 5 6
    7 8 9
    10 11 12
    

2.5.3 工作原理

xargs命令数量众多的选项使其能够适用于多种问题场景。让我们来看看如何能够巧妙地运用这些选项来解决问题。

可以用自己的定界符来分隔参数。用-d选项为输入指定一个定制的定界符:

$ echo "splitXsplitXsplitXsplit" | xargs -d X
split split split split

在上面的代码中,stdin是一个包含了多个X字符的字符串。我们可以用-dX作为输入定界符。在这里,我们明确指定X作为输入定界符,而在默认情况下,xargs采用内部字段分隔符(空格)作为输入定界符。

结合-n选项,我们可以将输入划分成多行,而每行包含两个参数:

$ echo "splitXsplitXsplitXsplit" | xargs -d X -n 2
split split
split split

2.5.4 补充内容

我们已经从上面的例子中学到了如何将stdin格式化成不同的输出形式以作为参数。现在让我们来学习如何将这些参数传递给命令。

  1. 读取stdin,将格式化参数传递给命令

    编写一个小型的定制版echo来更好地理解用xargs提供命令行参数的方法:

    #!/bin/bash
    #文件名: cecho.shecho $*'#'

    当参数被传递给文件cecho.sh后,它会将这些参数打印出来,并以 # 字符作为结尾。例如:

    $ ./cecho.sh arg1 arg2
    arg1 arg2 #
    

    让我们来看下面这个问题。

    • 有一个包含着参数列表的文件(每行一个参数)。我需要用两种方法将这些参数传递给一个命令(比如cecho.sh)。第一种方法,需要每次提供一个参数:

      ./cecho.sh arg1
      ./cecho.sh arg2
      ./cecho.sh arg3

      或者,每次需要提供两个或三个参数。提供两个参数时,它看起来像这样:

      ./cecho.sh arg1 arg2
      ./cecho.sh arg3
    • 第二种方法,需要一次性提供所有的命令参数:

      ./cecho.sh arg1 arg2 arg3

    先别急着往下看,试着运行一下上面的命令,然后仔细观察输出结果。

    上面的问题也可以用xargs来解决。我们有一个名为args.txt的参数列表文件,这个文件的内容如下:

    $ cat args.txt
    arg1
    arg2
    arg3
    

    就第一个问题,我们可以将这个命令执行多次,每次使用一个参数:

    $ cat args.txt | xargs -n 1 ./cecho.sh
    arg1 #
    arg2 #
    arg3 #
    

    每次执行需要X个参数的命令时,使用:

    INPUT | xargs -n X

    例如:

    $ cat args.txt | xargs -n 2 ./cecho.sh
    arg1 arg2 #
    arg3 #
    

    就第二个问题,为了在执行命令时一次性提供所有的参数,可以使用:

    $ cat args.txt | xargs ./cecho.sh
    arg1 arg2 arg3 #
    

    在上面的例子中,我们直接为特定的命令(例如cecho.sh)提供命令行参数。这些参数都源于args.txt文件。但实际上除了它们外,我们还需要一些固定不变的命令参数。思考下面这种命令格式:

    ./cecho.sh -p arg1 -l

    在上面的命令执行过程中,arg1是唯一的可变内容,其余部分都保持不变。我们可以从文件(args.txt)中读取参数,并按照下面的方式提供给命令:

    ./cecho.sh -p arg1 -l
    ./cecho.sh -p arg2 -l
    ./cecho.sh -p arg3 -l

    xargs有一个选项-I,可以提供上面这种形式的命令执行序列。我们可以用-I指定替换字符串,这个字符串在xargs扩展时会被替换掉。如果将-Ixargs结合使用,对于每一个参数,命令都会被执行一次。

    试试下面的用法:

    $ cat args.txt | xargs -I {} ./cecho.sh -p {} -l
    -p arg1 -l #
    -p arg2 -l #
    -p arg3 -l #
    

    -I {}指定了替换字符串。对于每一个命令参数,字符串{}都会被从stdin读取到的参数替换掉。

    使用-I的时候,命令以循环的方式执行。如果有3个参数,那么命令就会连同{}一起被执行3次。在每一次执行中{}都会被替换为相应的参数。

  2. 结合find使用xargs

    xargsfind算是一对死党。两者结合使用可以让任务变得更轻松。不过人们通常却是以一种错误的组合方式使用它们。例如:

    $ find . -type f -name "*.txt"  -print | xargs rm -f
    

    这样做很危险。有时可能会删除不必要删除的文件。我们没法预测分隔find命令输出结果的定界符究竟是什么('\n'或者' ')。很多文件名中都可能会包含空格符(' '),因此xargs很可能会误认为它们是定界符(例如,hell text.txt会被xargs误解为hell和text.txt)。

    只要我们把find的输出作为xargs的输入,就必须将-print0find结合使用,以字符null('\0')来分隔输出。

    find匹配并列出所有的 .txt文件,然后用xargs将这些文件删除:

    $ find . -type f -name "*.txt" -print0 | xargs -0 rm -f
    

    这样就可以删除所有的.txt文件。xargs -0\0作为输入定界符。

  3. 统计源代码目录中所有C程序文件的行数

    统计所有C程序文件的行数(Lines of Code,LOC)是大多数程序员都会遇到的任务。完成这项任务的代码如下:

    $ find source_code_dir_path -type f -name "*.c" -print0 | xargs -0 wc -l
    

    如果你想获得有关个人源代码更多的统计信息,有个叫做SLOCCount的工具可以派上用场。现代GNU/Linux发行版一般都包含这个软件包,或者你也可以从http://www.dwheeler.com/sloccount/处下载。

  4. 结合stdin,巧妙运用while语句和子shell

    xargs只能以有限的几种方式来提供参数,而且它也不能为多组命令提供参数。要执行包含来自标准输入的多个参数的命令,有一种非常灵活的方法。包含while循环的子shell可以用来读取参数,然后通过一种巧妙的方式执行命令:

    $ cat files.txt  | ( while read arg; do cat $arg; done )
    # 等同于cat files.txt | xargs -I {} cat {}
    

    while循环中,可以将cat``$arg替换成任意数量的命令,这样我们就可以对同一个参数执行多条命令。也可以不借助管道,将输出传递给其他命令。这个技巧能够适用于各种问题场景。子shell操作符内部的多个命令可作为一个整体来运行。

    $ cmd0 | ( cmd1;cmd2;cmd3) | cmd4

    如果cmd1cd /,那么就会改变子shell工作目录,然而这种改变仅局限于子shell内部。cmd4则完全不知道工作目录发生了变化。

linux xargs相关推荐

  1. linux xargs命令

    |--linux xargs命令 xargs 是给命令传递参数的一个过滤器,也是组合多个命令的一个工具. xargs 可以将管道或标准输入(stdin)数据转换成命令行参数, 也能够从文件的输出中读取 ...

  2. linux xargs命令_如何在Linux中使用xargs命令?

    linux xargs命令 The xargs command allows us to pass the output of one command as the input for another ...

  3. linux xargs

    http://www.centrue.me/2011/09/01/linux-xargs-find/ Linux中xargs的用法 Posted on  September 1, 2011 仅对上文F ...

  4. linux xargs cp,Linux xargs命令的使用

    1.功能: xargs可以将stdin中以空格或换行符进行分隔的数据,形成以空格分隔的参数(arguments),传递给其他命令.因为以空格作为分隔符,所以有一些文件名或者其他意义的名词内含有空格的时 ...

  5. linux xargs与管道的区别

    为什么要用xargs,问题的来源 在工作中经常会接触到xargs命令,特别是在别人写的脚本里面也经常会遇到,但是却很容易与管道搞混淆,本篇会详细讲解到底什么是xargs命令,为什么要用xargs命令以 ...

  6. linux xargs 给命令传递参数 组合多个命令

    简介 之所以能用到这个命令,关键是由于很多命令不支持|管道来传递参数,而日常工作中有有这个必要,所以就有了xargs命令,例如: 这个命令是错误的 find /sbin -perm +700 |ls ...

  7. Linux xargs命令

    xargs命令是给其他命令传递参数的一个过滤器,也是组合多个命令的一个工具. 之所以能用到这个命令,关键是由于很多命令不支持|管道来传递参数.通常Linux命令可以用 | 首尾相连,上一个命令的 st ...

  8. Linux xargs 命令

    2015-08-29 创建 1.概述 从标准输入中创建并且执行命令行. xargs 从标准输入中读取条目,使用空格(这样可以保护单双引号或者反斜杠)或者换行符分隔,并且执行(默认是 /bin/echo ...

  9. Linux xargs 用法详解

    1. 简介 之所以能用到这个命令,关键是由于很多命令不支持|管道来传递参数,而日常工作中有有这个必要,所以就有了xargs命令,例如: find /sbin -perm +700 |ls -l     ...

最新文章

  1. 干货:如何利用机器学习实现有噪声标签样本分类模型?
  2. dfs.datanode.max.xcievers参数导致hbase集群报错
  3. vue 右键菜单插件 简单、可扩展、样式自定义的右键菜单
  4. mysql 5.7.11 x64_mysql 5.7.11 winx64安装配置教程
  5. 《完全写作指南》随笔
  6. Ubuntu20安装RTL8811/RTL8812无线网卡驱动
  7. zabbix日志监控
  8. 数据库系统原理与应用教程(081)—— MySQL 视图(View)的创建与使用
  9. 剖析微商到微伤的全过程
  10. 解决由于ntoskrnl.exe导致的蓝屏
  11. CMA-ES算法解决连续优化问题
  12. Unity 生成原始LUT用于外部校色相机不透明物体截图
  13. 修改hosts文件(win10版)
  14. 为什么CNN可以自动提取图像特征???(2)
  15. 2016年9月2日 星期五 --出埃及记 Exodus 16:34
  16. 吴恩达ML WEEK7 机器学习
  17. 是不是虚拟内存越大越好
  18. SAP顾问生涯闲记:做过的最好玩的Global项目是什么样子
  19. 分流稳压器TL431/TLV431
  20. 操作:IPSec连接配置

热门文章

  1. 第二讲 HTML再识(一)
  2. 几个目标检测算法的比较——yolov4,yolov4-tiny,faster-rcnn
  3. 【Node.js-6】consolidate模板引擎集成、router路由介绍
  4. php怎么爬取亚马逊的数据,php 抓取亚马逊中国产品数据-标题,价格,首图片
  5. 浏览器网页谷歌翻译-使用js脚本
  6. python中如何移动图形工作站_Schrodinger分子动力模拟与建模工作站配置推荐
  7. 图解:什么是红黑树?(下篇)
  8. 运动搜索算法之钻石搜索
  9. 计算机毕业设计Java新冠疫苗接种预约系统登录(源码+系统+mysql数据库+Lw文档)
  10. 计算机网络期中考试,计算机网络期末考试试题及答案_计算机网络试题及答案...