知乎专栏 |
xargs命令是 给其他命令传递参数的一个过滤器,也是组合多个命令的一个工具 它擅长将标准输入数据转换成命令行参数,xargs能够处理管道或者stdin并将其转换成特定命令的命令参数. xargs也可以将单行或多行文本输入转换为其他格式,例如多行变单行,单行变多行. xargs的默认命令是echo,空格是默认定界符;这意味着通过管道传递给xargs的输入将会包含换行和空白,不过通过xargs的处理,换行和空白将被空格取代.
xargs命令用法
xargs用作替换工具,读取输入数据重新格式化后输出。
定义一个测试文件,内有多行文本数据: cat >> test.txt <<EOF a 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 EOF # cat test.txt a 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 多行输入一行输出: # cat test.txt | xargs a 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 等效 # cat test.txt | tr "\n" " " a 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
# xargs < test.txt a 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 # cat /etc/passwd | cut -d : -f1 > users # xargs -n1 < users echo "Your name is" Your name is root Your name is bin Your name is daemon Your name is adm Your name is lp Your name is sync Your name is shutdown Your name is halt Your name is mail Your name is operator Your name is games Your name is ftp Your name is nobody Your name is dbus Your name is polkitd Your name is avahi Your name is avahi-autoipd Your name is postfix Your name is sshd Your name is neo Your name is ntp Your name is opendkim Your name is netkiller Your name is tcpdump
-I R same as --replace=R
复制所有图片文件到 /data/images 目录下: ls *.jpg | xargs -n1 -I cp {} /data/images
读取stdin,将格式化后的参数传递给命令xargs的一个选项-I,使用-I指定一个替换字符串{},这个字符串在xargs扩展时会被替换掉,当-I与xargs结合使用,每一个参数命令都会被执行一次: # echo "name=Neo|age=30|sex=T|birthday=1980" | xargs -d"|" -n1 | xargs -I {} echo "select * from tab where {} " select * from tab where name=Neo select * from tab where age=30 select * from tab where sex=T select * from tab where birthday=1980 # xargs -I user echo "Hello user" <users Hello root Hello bin Hello daemon Hello adm Hello lp Hello sync Hello shutdown Hello halt Hello mail Hello operator Hello games Hello ftp Hello nobody Hello dbus Hello polkitd Hello avahi Hello avahi-autoipd Hello postfix Hello sshd Hello netkiller Hello neo Hello tss Hello ntp Hello opendkim Hello noreply Hello tcpdump
-I 使用-I指定一个替换字符串,这个字符串在xargs扩展时会被替换掉,当-I与xargs结合使用,每一个参数命令都会被执行一次. mysql -u root -predhat -s -e "show databases" | egrep "^mt4_user_equity_" | xargs -I "@@" mysql -u root -predhat -e "DROP DATABASE \`@@\`;"
-n 参数來指定每一次执行指令所使用的参数个数上限值.
-n选项多行输出: # cat test.txt | xargs -n3 a 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 # cat test.txt | xargs -n4 a 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 # cat test.txt | xargs -n5 a 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 [neo@netkiller test]# echo 'a b c d e 1 2 3 4 5' | xargs -n 5 a b c d e 1 2 3 4 5
-t 参数可以让 xargs 在执行指令之前先显示要执行的指令
[neo@netkiller test]# echo a b c d e f | xargs -t /bin/echo a b c d e f a b c d e f
-d 自定义一个定界符 默认是空格
[neo@netkiller test]# echo 'abc' | xargs -d b a c -d选项可以自定义一个定界符: # echo "name|age|sex|birthday" | xargs -d"|" name age sex birthday 结合-n选项使用: # echo "name=Neo|age=30|sex=T|birthday=1980" | xargs -d"|" -n1 name=Neo age=30 sex=T birthday=1980
-0 是以null字符结尾的,而不是以白空格(whitespace)结尾的且引号和反斜杠,都不是特殊字符;
每个输入的字符,都视为普通字符禁止掉文件结束符,被视为别的参数.当输入项可能包含白空格,引号,反斜杠等情况时,才适合用此参数 [neo@netkiller test]# touch "Mr liu" [neo@netkiller test]# ls M* Mr liu [neo@netkiller test]# find -type f -name "Mr*" | xargs rm -f [neo@netkiller test]# ls M* Mr liu [neo@netkiller test]# find -type f -name "Mr*" | xargs -t rm -f rm -f ./Mr liu // 这个时候我们可以将 find 指令加上 -print0 参数,另外将 xargs 指令加上 -0 参数,改成这样: [neo@netkiller test]# find -type f -name "Mr*" -print0| xargs -t -0 rm -f rm -f ./Mr liu [neo@netkiller test]# ls M* ls: 无法访问M*: 没有那个文件或目录
-r 如果标准输入不包含任何非空格,请不要运行该命令.
[neo@netkiller test]# echo a b c d e f | xargs -p -n 3 /bin/echo a b c ?...n /bin/echo d e f ?...n /bin/echo ?...n //当我们使用 -p 参数时,如果所有的指令都输入 n 跳过不执行时候,最后还会出现一个沒有任何参数的 echo 指令, 如果想要避免以這种空字串作为参数来执行指令,可以加上 -r 参数 [neo@netkiller test]# echo a b c d e f | xargs -p -n 3 -r /bin/echo a b c ?...n /bin/echo d e f ?...n
由于 docker images|grep none|awk '{print $3}' 返回空字符串,提示 Remove one or more images,使用 -r 参数判断返回字符串为空,不再执行后面的命令。
[root@netkiller watch]# docker images|grep none|awk '{print $3}'|xargs docker rmi -f > /dev/null "docker rmi" requires at least 1 argument. See 'docker rmi --help'. Usage: docker rmi [OPTIONS] IMAGE [IMAGE...] Remove one or more images [root@netkiller watch]# docker images|grep none|awk '{print $3}'|xargs -r docker rmi -f > /dev/null