Linux之xargs的用法
5年前
3092
0
xargs 是 execute arguments 的缩写,它的作用是从标准输入中读取内容,并将此内容传递给它要协助的命令,并作为那个命令的参数来执行。
xargs是什么
xargs命令是给其他命令传递参数的一个过滤器,也是组合多个命令的一个工具。
为什么要用xargs
有时候我们的脚本却需要 echo ‘516’ | kill 这样的效果,例如 ps -ef | grep ‘test’ | kill 这样的效果,筛选出符合某条件的进程pid然后结束。这种需求对于我们来说是理所当然而且是很常见的,那么应该怎样达到这样的效果呢。有几个解决办法:
通过 kill
ps -ef | grep 'ddd'
这种形式,这个时候实际上等同于拼接字符串得到的命令,其效果类似于 kill $pidfor procid in $(ps -aux | grep “some search” | awk ‘{print $2}’); do kill -9 $procid; done
其实与第一种原理一样,只不过需要多次kill的时候是循环处理的,每次处理一个ps -ef | grep ‘ddd’ | xargs kill
没错,这就是本文的主人公,xargs命令可以通过管道接受字符串,并将接收到的字符串通过空格分割成许多参数(默认情况下是通过空格分割) 然后将参数传递给其后面的命令,作为后面命令的命令行参数
xargs能做什么
它擅长将标准输入数据转换成命令行参数,xargs能够处理管道或者stdin并将其转换成特定命令的命令参数。
xargs也可以将单行或多行文本输入转换为其他格式,例如多行变单行,单行变多行。
xargs的默认命令是echo,空格是默认定界符。这意味着通过管道传递给xargs的输入将会包含换行和空白,不过通过xargs的处理,换行和空白将被空格取代。xargs是构建单行命令的重要组件之一。
xargs怎么用
xargs用作替换工具,读取输入数据重新格式化后输出,下面就给大家介绍一下怎么使用xargs。
xargs用法格式是这样的:
command | xargs -item command
xargs与管道有什么不同
为了能够为大家解释清楚 xargs 和管道的关系,我们这次选用了更加典型的 cat 命令来为大家举例。
xargs与管道有什么不同呢,这是两个很容易混淆的东西,看了上面的xargs的例子还是有点云里雾里的话,我们来看下面的例子弄清楚为什么需要xargs:
[www.itselfstudy.cn]# echo '--help' | cat
--help
[www.itselfstudy.cn]# echo '--help' | xargs cat
Usage: cat [OPTION]... [FILE]...
Concatenate FILE(s), or standard input, to standard output.
-A, --show-all equivalent to -vET
-b, --number-nonblank number nonempty output lines
-e equivalent to -vE
-E, --show-ends display $ at end of each line
-n, --number number all output lines
....
# 省略后面内容
可以看到 echo ‘—help’ | cat 该命令输出的是echo的内容,也就是说将echo的内容当作cat处理的文件内容了,实际上就是echo命令的输出通过管道定向到cat的输入了。然后cat从其标准输入中读取待处理的文本内容。这等价于在test.txt文件中有一行字符 ‘—help’ 然后运行 cat test.txt 的效果。
而 echo ‘—help’ | xargs cat 等价于 cat —help 什么意思呢,就是xargs将其接受的字符串 —help 做成cat的一个命令参数来运行cat命令,同样 echo ‘test.c test.cpp’ | xargs cat 等价于 cat test.c test.cpp 此时会将test.c和test.cpp的内容都显示出来。
xargs参数选项
下面介绍一下xargs 后面的参数 -item
具体含义:
-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 从标准输入一次读取 num 行送给 command 命令。
-l 同 -L。
-d delim 分隔符,默认的xargs分隔符是回车,argument的分隔符是空格,这里修改的是xargs的分隔符。
-x exit的意思,主要是配合-s使用。。
-P 修改最大的进程数,默认是1,为0时候为as many as it can ,这个例子我没有想到,应该平时都用不到的吧。
示例
首先定义一个测试文件,内有多行文本数据:
[www.itselfstudy.cn]# 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
下面看一下使用xargs效果,单行输出:
[www.itselfstudy.cn]# 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
1. -n 选项多行输出:
[www.itselfstudy.cn]# 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
2. -d 选项可以自定义一个定界符:
[www.itselfstudy.cn]# echo "nameXnameXnameXname" | xargs -dX
name name name name
结合-n选项使用:
[www.itselfstudy.cn]# echo "nameXnameXnameXname" | xargs -dX -n2
name name
name name
3. xargs的一个选项-I,使用-I指定一个替换字符串{},这个字符串在xargs扩展时会被替换掉,当-I与xargs结合使用,每一个参数命令都会被执行一次:
[www.itselfstudy.cn]# cat arg.txt | xargs -I {} ./sk.sh -p {} -l
-p aaa -l
-p bbb -l
-p ccc -l
4. 复制所有图片文件到 /data/images 目录下:
ls *.jpg | xargs -n1 -I cp {} /data/images
5. 假如你有一个文件包含了很多你希望下载的URL,你能够使用xargs下载所有链接:
cat url-list.txt | xargs wget -c
6. 查找所有的 jpg 文件,并且压缩它们:
find . -type f -name "*.jpg" -print | xargs tar -czvf images.tar.gz
7. 统计一个源代码目录中所有php文件的行数:
find . -type f -name "*.php" -print0 | xargs -0 wc -l
8. 查找系统中的每一个普通文件,然后使用xargs命令来测试他们分别属于哪类文件
find . -type f -print | xargs file
9. 在整个系统中查找内存信息存储文件(core dump),然后把结果保存到/tmp/core.log文件中
find / -name "core" -print | xargs echo "" > /tmp/core.log
10. 在当前目录下查找所有用户具有读、写和执行权限的文件。并收回相应的写权限
find . -perm -7 -print | xargs chmod o-w
11. 用grep命令在所有的普通文件中搜索hostname这个词
find . -type f -print | xargs grep "hostname"
12. 用grep命令在当前目录下的所有普通文件中搜索hostnames这个词
find . -name * -type f -print | xargs grep "hostnames"
# \用来取消find命令中的*在shell中的特殊含义
13. 使用xargs执行mv
find . -name "*.log" | xargs -i mv {} test4
14. find后执行xargs提示xargs:argument line too long解决方法:
find . -type f -atime +0 -printf0 | xargs -0 -11 -t rm -f
find . -type f -atime +0 -print0 | xargs -0 -l1 -t rm -f
-l1是一次处理一个;-t是处理之前打印出命令
15. xargs的-p参数的使用
find . -name "*.log" | xargs -p -i mv {} ..
-p参数会提示让你确认是否执行后面的命令,y执行,n不执行。
16. 删除 /home/omc/ftl/下的log文件
ll *.log |xargs rm -rf {} #【错误】
rm: invalid option -- 'w' ll 不能删除、复制
Try 'rm --help' for more information.
ls *.log |xargs rm -rf {} #【正确】
17. 在当前目录下查找所有用户权限644的文件,并更改权限600
find /home/omc/ftl -perm 644 | xargs chmod 600
18. -E 选项,有的系统的xargs版本可能是-e eof-str
该选项指定一个字符串,当xargs解析出多个命令行参数的时候,如果搜索到-e指定的命令行参数,则只会将-e指定的命令行参数之前的参数(不包括-e指定的这个参数)传递给xargs后面的命令
echo '11 22 33' | xargs -E '33' echo
# 输出:11 22
注意:-E只有在xargs不指定-d的时候有效,如果指定了-d则不起作用,而不管-d指定的是什么字符,空格也不行
echo '11 22 33' | xargs -d ' ' -E '33' echo
# 输出 11 22 33
echo '11@22@33@44@55@66@77@88@99@00 aa 33 bb' | xargs -E '33' -d '@' -p echo
# 输出 11 22 33 44 55 66 77 88 99 00 aa 33 bb
参考文献:
https://www.runoob.com/linux/linux-comm-xargs.html
https://www.cnblogs.com/wangqiguo/p/6464234.html#_label0