博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
xargs命令
阅读量:4704 次
发布时间:2019-06-10

本文共 5448 字,大约阅读时间需要 18 分钟。

xargs命令

今天在使用find 命令的时候想将查找的结果进行处理,然后就想到了find的用法 exec和xargs这两个参数;
不过在使用find --help时发现xargs并不是find的参数,我猜想xargs是一条独立的命令;
百度到一条重要信息,find不支持管道命令

之前一直认为管道命令无敌,百度到这个结果后管道"|"在我心中的形象突然崩塌

言归正传:

一、管道命令
  重新认识下管道命令:
    管道命令操作符是:”|”,它仅能处理经由前面一个指令传出的正确输出信息,也就是 standard output 的信息,
    对于 stdandard error 信息没有直接处理能力。然后,传递给下一个命令,作为标准的输入 standard input.
  
    command1正确输出,作为command2的输入 然后comand2的输出作为,comand3的输入 ,comand3输出就会直接显示在屏幕上面了。
    通过管道之后:comand1,comand2的正确输出不显示在屏幕上面
  注意:
    1、管道命令只处理前一个命令正确输出,不处理错误输出
    2、管道命令右边命令,必须能够接收标准输入流命令才行。
  实例

/home目录下只有1.txt cassandra a.txt scripts test.sh test1.sh b.txt几个文件,没有test2.sh文件[root@localhost home]# cat test1.sh | ls1.txt cassandra chazhaomulu.txt scripts test.sh test1.sh tihuanmubiao.txt[root@localhost home]# cat test1.sh line1line2line3line4echo "very good!";line6echo "good!";line8echo "pass!";line10echo "no pass!";[root@localhost home]# cat test1.sh | grep -n 'echo'5:	echo "very good!";7:	echo "good!";9:	echo "pass!";11:	echo "no pass!";#读出test1.sh文件内容,通过管道转发给grep 作为输入内容[root@localhost home]# cat test1.sh test2.sh | grep -n 'echo'cat: test2.sh: No such file or directory5:	echo "very good!";7:	echo "good!";9:	echo "pass!";11:	echo "no pass!";#cat test2.sh不存在,错误输出打印到屏幕,正确输出通过管道发送给grep [root@localhost home]# cat test1.sh test2.sh 2>/dev/null | grep -n 'echo'5:	echo "very good!";7:	echo "good!";9:	echo "pass!";11:	echo "no pass!";#将test2.sh 没有找到错误输出重定向输出给/dev/null 文件,正确输出通过管道发送给grep[root@localhost home]# cat test1.sh | ls1.txt cassandra a.txt scripts test.sh test1.sh b.txt

  

    #读取test1.sh内容,通过管道发送给ls命令,由于ls 不支持标准输入,因此数据被丢弃

    管道沟通的是 标准输入输出(stdin/stdout),ls命令接受的路径是 命令行参数 。(读取的是命令行参数,而不是 stdin。)
    上面例子中cat test1.sh | ls,目的是用ls列出file(test1.sh)文件中的每一行路径的内容。
    ls是以类似ls /path/to/file这种方式调用的,你需要的不是管道,而是ls $(cat file)
    相当多命令是同时可以接受两者的,容易造成混乱;
    cat/ls只支持命令行参数。但没有人规定一定要同时支持两者。
    例子:
    vim编辑文件时用的命令是vim file,但如果要从stdin读入编辑内容的话就需要使用echo "gagagagaggaga" | vim -。
    在vim后面加上一个参数-来告诉vim调整行为,改为从stdin读入内容。
    PS:
    遇到这种命令就需要使用xargs了;
    查看一个命令是否支持stdin,看man(--help)就可以了
    example:
    ls:List information about the FILEs (the current directory by default).
    wc:With no FILE, or when FILE is -, read standard input.

    cat file|awk -f script #(UUOC)效果上与
    awk -f script file 一样。
    关于管道命令与重定向区别、shell脚本接收管道输入:
二、xargs命令
  1.关于xargs的描述

    xargs 读入stdin的数据,并且以空格符或断行符进行分辨,将stdin的数据分隔为arguments

    xargs命令是给其他命令传递参数的一个过滤器,也是组合多个命令的一个工具。
    它擅长将标准输入数据转换成命令行参数,xargs能够处理管道或者stdin并将其转换成特定命令的命令参数。
    xargs也可以将单行或多行文本输入转换为其他格式,例如多行变单行,单行变多行。
    xargs的默认命令是echo,空格是默认定界符。
    这意味着通过管道传递给xargs的输入将会包含换行和空白,不过通过xargs的处理,换行和空白将被空格取代。
    xargs是构建单行命令的重要组件之一
  2.选项解释

-0 当sdtin含有特殊字元时候,将其当成一般字符,像\'空格等例如:	[root@localhost home]# echo "\\"|xargs echo[root@localhost home]# echo "\\"|xargs -0 echo\-a file 从文件中读入作为sdtin-e flag ,注意有的时候可能会是-E,flag必须是一个以空格分隔的标志,当xargs分析到含有flag这个标志的时候就停止。-p 当每次执行一个argument的时候询问一次用户。-n num 后面加次数,表示命令在执行的时候一次用的argument的个数,默认是用所有的。-t 表示先打印命令,然后再执行。-i 或者是-I,这得看Linux支持了,将xargs的每项名称,一般是一行一行赋值给{},可以用{}代替。-r no-run-if-empty 当xargs的输入为空的时候则停止xargs,不用再去执行了。-s num 命令行的最好字符数,指的是xargs后面那个命令的最大命令行字符数。	-L num Use at most max-lines nonblank input lines per command line.-s是含有空格的。-l 同-L-d delim 分隔符,默认的xargs分隔符是回车,argument的分隔符是空格,这里修改的是xargs的分隔符-x exit的意思,主要是配合-s使用。-P 修改最大的进程数,默认是1,为0时候为as many as it can ,这个例子我没有想到,应该平时都用不到的吧。

  

  3.xargs命令用法

    xargs用作替换工具,读取输入数据重新格式化后输出。

(a)定义一个测试文件,内有多行文本数据:[root@localhost home]# cat test.txt a b c d e f gh i j k l m no p qr s tu v w x y z(b)多行输入单行输出:[root@localhost home]# cat test.txt | xargsa b c d e f g h i j k l m n o p q r s t u v w x y z(c)-n选项多行输出:[root@localhost home]# cat test.txt | xargs -n3a b cd e fg h ij k lm n op q rs t uv w xy z(d)-d选项可以自定义一个定界符:[root@localhost home]# echo "nameXnameXnameXname" | xargs -dXname name name name结合-n选项使用:[root@localhost home]# echo "nameXnameXnameXname" | xargs -dX -n2name namename name(e)读取stdin,将格式化后的参数传递给命令假设一个命令为 sk.sh 和一个保存参数的文件arg.txt:(需要加执行权限)#!/bin/bash#sk.sh命令内容,打印出所有参数。echo $* arg.txt文件内容:cat arg.txtaaabbbccc<1>xargs的一个选项-I,使用-I指定一个替换字符串{},这个字符串在xargs扩展时会被替换掉,当-I与xargs结合使用,每一个参数命令都会被执行一次:cat arg.txt | xargs -I {} ./sk.sh -p {} -l-p aaa -l-p bbb -l-p ccc -l<2>复制所有图片文件到 /data/images 目录下:ls *.jpg | xargs -n1 -I cp {} /data/images#(h)xargs结合find使用用rm 删除太多的文件时候,可能得到一个错误信息:/bin/rm Argument list too long. 用xargs去避免这个问题:find . -type f -name "*.log" -print0 | xargs -0 rm -fxargs -0:当sdtin含有特殊字元时候,将其当成一般字符,像\'空格等;防止名称中包含空格等特殊字符/**注释Items are separated by a null, not whitespace.Disables quote and backslash processing项目被Null而不是空格分隔开,禁用引用和反斜杠处理**/统计一个源代码目录中所有php文件的行数:find . -type f -name "*.php" -print0 | xargs -0 wc -l查找所有的jpg 文件,并且压缩它们:find . -type f -name "*.jpg" -print | xargs tar -czvf images.tar.gz(i)xargs其他应用假如你有一个文件包含了很多你希望下载的URL,你能够使用xargs下载所有链接:cat url-list.txt | xargs wget -c

  

  3.子Shell(Subshells)

    运行一个shell脚本时会启动另一个命令解释器.,就好像你的命令是在命令行提示下被解释的一样,类似于批处理文件里的一系列命令。
    每个shell脚本有效地运行在父shell(parent shell)的一个子进程里。
    这个父shell是指在一个控制终端或在一个xterm窗口中给你命令指示符的进程。
    cmd1 | ( cmd2; cmd3; cmd4 ) | cmd5
    如果cmd2 是cd /,那么就会改变子Shell的工作目录,这种改变只是局限于子shell内部,cmd5则完全不知道工作目录发生的变化。
    子shell是嵌在圆括号()内部的命令序列,子Shell内部定义的变量为局部变量。 子shell可用于为一组命令设定临时的环境变量:
    COMMAND1
    COMMAND2
    COMMAND3
    (
      IFS=:
      PATH=/bin
      unset TERMINFO
      set -C shift 5
      COMMAND4
      COMMAND5
      exit 3 # 只是从子shell退出。
    )
    # 父shell不受影响,变量值没有更改。
    COMMAND6
    COMMAND7

 更多xargs补充:

转载于:https://www.cnblogs.com/irockcode/p/6913567.html

你可能感兴趣的文章
Rule 12: Remove Duplicate Scripts(Chapter 12 of High performance Web Sites)
查看>>
缓存服务的更新策略有哪些?
查看>>
RMAN还原时注意set newname时文件名不要有空格
查看>>
一种链表的实现
查看>>
vue中ESlint报错
查看>>
NetCore2.0 RozarPage自动生成增删改查
查看>>
0816 1459 json & pickle ,目录导入,目录规范
查看>>
Servlet 生命周期
查看>>
HDU 1398
查看>>
(转)Linux-HA实战(1)— Heartbeat安装
查看>>
如何恢复oracle中已删除的表
查看>>
双向BFS(转)
查看>>
【最短路】Dijkstra+ 链式前向星+ 堆优化(优先队列)
查看>>
linux下实现keepalived+nginx高可用
查看>>
【BZOJ3791】作业
查看>>
Html Agility Pack解析Html(C#爬虫利器)
查看>>
GridView中的CheckBox选中 (JQuery)
查看>>
webform(四)简单控件
查看>>
验证码
查看>>
敏捷开发入门教程
查看>>