不知道大家有没有碰着过这样的情形,有两条命令,后面一条命令依赖前面命令返回的列表数据作为参数。例如须要找出指定进程名字的所有进程的绝对路径。常规的方法便是先通过ps得到pid,再在for循环里通过ls列出proc目录下的路径信息。以下是脚本例子:
#! /bin/bash if [ $# -ne 1 ] ; then echo \"大众Usage: psd exe\"大众 exit 1 fi for pid in `ps -e | grep | awk '{print }'` ; do echo -n \公众${pid} \"大众 ls -l /proc/${pid}/exe | awk '{print }' done
但是如果你不想利用脚本,仅通过一条命令,如何做到呢?这里就到xargs出马的时候了,只须要一条命令:
ps axu | grep \公众java\公众 | grep -v \"大众grep\"大众 | awk '{print $2}|xargs -I {} ls -l /proc/{}/exe
是不是大略很多?xargs命令实在是给其他命令通报参数的一个过滤器,也是组合多个命令的一个工具。它善于将标准输入数据转换成命令行参数,xargs能够处理管道或者stdin并将其转换成特定命令的命令参数。xargs也可以将单行或多行文本输入转换为其他格式,例如多行变单行,单行变多行。xargs的默认命令是echo,空格是默认定界符。这意味着通过管道通报给xargs的输入将会包含换行和空缺,不过通过xargs的处理,换行和空缺将被空格取代。xargs是构建单行命令的主要组件之一。
xargs用作更换工具,读取输入数据重新格式化后输出。
定义一个测试文件,内有多行文本数据:
cat test.txta b c d e f gh i j k l m no p qr s tu v w x y z
多行输入单行输出:
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
-n选项多行输出:
cat test.txt | xargs -n3a b cd e fg h ij k lm n op q rs t uv w xy z
-d选项可以自定义一个定界符:
echo \"大众nameXnameXnameXname\"大众 | xargs -dXname name name name
结合-n选项利用:
echo \公众nameXnameXnameXname\公众 | xargs -dX -n2name namename name
读取stdin,将格式化后的参数通报给命令
假设一个命令为 sk.sh 和一个保存参数的文件arg.txt:
#!/bin/bash#sk.sh命令内容,打印出所有参数。echo $arg.txt文件内容:cat arg.txtaaabbbccc
xargs的一个选项-I,利用-I指定一个更换字符串{},这个字符串在xargs扩展时会被更换掉,当-I与xargs结合利用,每一个参数命令都会被实行一次:
cat arg.txt | xargs -I {} ./sk.sh -p {} -l-p aaa -l-p bbb -l-p ccc -l
复制所有图片文件到 /data/images 目录下:
ls .jpg | xargs -n1 -I cp {} /data/images
xargs结合find利用
用rm 删除太多的文件时候,可能得到一个缺点信息:/bin/rm Argument list too long. 用xargs去避免这个问题:
find . -type f -name \"大众.log\公众 -print0 | xargs -0 rm -f
xargs -0将\0作为定界符。
统计一个源代码目录中所有php文件的行数:
find . -type f -name \"大众.php\公众 -print0 | xargs -0 wc -l
查找所有的jpg 文件,并且压缩它们:
find . -type f -name \公众.jpg\公众 -print | xargs tar -czvf images.tar.gz
xargs其他运用
如果你有一个文件包含了很多你希望下载的URL,你能够利用xargs下载所有链接:
cat url-list.txt | xargs wget -c