Linux-xargs命令
http://www.jb51.net/article/44720.htm
http://blog.csdn.net/yangshangwei/article/details/52666202
xargs是给命令传递参数的一个过滤器,也是组合多个命令的一个工具。它把一个数据流分割为一些足够小的块,以方便过滤器和命令进行处理。通常情况下,xargs从管道或者stdin中读取数据,但是它也能够从文件的输出中读取数据。xargs的默认命令是echo,这意味着通过管道传递给xargs的输入将会包含换行和空白,不过通过xargs的处理,换行和空白将被空格取代。
该命令的主要功能是从输入中构建和执行shell命令。
在使用find命令的-exec选项处理匹配到的文件时,
find命令将所有匹配到的文件一起传递给exec执行。但有些系统对能够传递给exec的命令长度有限制,这样在find命令运行几分钟之后,就会出现溢出错误。错误信息通常是“参数列太长”或“参数列溢出”。这就是xargs命令的用处所在,特别是与find命令一起使用。
find命令把匹配到的文件传递给xargs命令,而xargs命令每次只获取一部分文件而不是全部,不像-exec选项那样。这样它可以先处理最先获取的一部分文件,然后是下一批,并如此继续下去。
在有些系统中,使用-exec选项会为处理每一个匹配到的文件而发起一个相应的进程,并非将匹配到的文件全部作为参数一次执行;这样在有些情况下就会出现进程过多,系统性能下降的问题,因而效率不高;
而使用xargs命令则只有一个进程。另外,在使用xargs命令时,究竟是一次获取所有的参数,还是分批取得参数,以及每一次获取参数的数目都会根据该命令的选项及系统内核中相应的可调参数来确定。
下面我们来看看xargs有哪些参数可以选择.
舟山ssl适用于网站、小程序/APP、API接口等需要进行数据传输应用场景,ssl证书未来市场广阔!成为创新互联的ssl证书销售渠道,可以享受市场价格4-6折优惠!如果有意向欢迎电话联系或者加微信:18980820575(备注:SSL证书合作)期待与您的合作!
options
-
-afile
: 从file中读入数据
$cat 1.txt aaa bbb ccc ddd a b $xargs -a 1.txt aaa bbb ccc ddd a b
-
-0
: 当输入有特殊字符时,将其当作一般字符处理,比如""和空格
$echo "// " | xargs // $echo "// " | xargs -0 //
-
-d
: 指定分隔符
$cat 1.txt
aaa bbb ccc ddd
a b $cat 1.txt | xargs -d 'c' aaa bbb ddd
a b
-
-Eeof-str
: 指定结束标志为eof-str,xargs处理到这个标志就会停止
$xargs -E 'ddd' -a 1.txt
aaa bbb ccc $xargs -E 'dd' -a 1.txt
aaa bbb ccc ddd a b $cat 1.txt | xargs -E 'ddd' aaa bbb ccc
-
-Ireplace-str
: 将每行输入输入内容替换为replace-str
$cat 1.txt
aaa bbb ccc ddd
a b $cat 1.txt | xargs -t -I {} echo {} >> 1.txt echo aaa bbb ccc ddd echo a b $cat 1.txt
aaa bbb ccc ddd
a b
aaa bbb ccc ddd
a b
-
-i
: 等同于-I{}
$cat 1.txt
aaa bbb ccc ddd
a b $cat 1.txt | xargs -t -i echo {} >> 1.txt echo aaa bbb ccc ddd echo a b $cat 1.txt
aaa bbb ccc ddd
a b
aaa bbb ccc ddd
a b
-
-Lmax-lines
: 每次读取max-line行输入交由xargs处理
$cat 1.txt
aaa bbb ccc ddd
a b $cat 1.txt |xargs -L 2
aaa bbb ccc ddd a b $cat 1.txt |xargs -L 1
aaa bbb ccc ddd
a b
-
-l
: 类似于-L,区别在于-l可以不指定参数,默认为1.
-
-nmax-args
: 每行执行max-args个输入,默认执行所有
$cat 1.txt | xargs -n 2
aaa bbb
ccc ddd
a b
-
-p
: 交互模式,执行前询问是否执行
$cat 1.txt | xargs -p
/bin/echo aaa bbb ccc ddd a b ?...y
aaa bbb ccc ddd a b $cat 1.txt | xargs -p
/bin/echo aaa bbb ccc ddd a b ?...n
-
-r
: 无输入则停止执行,默认至少执行1次
$ echo ""|xargs -t mv
mv mv: missing file operand
Try `mv --help` for more information.
$ echo ""|xargs -t -r mv #直接退出
-
-smax-chars
:xargs每次执行命令的最大长度(含空格)
$ cat 1.txt
aaa bbb ccc ddd a b
$ cat 1.txt |xargs -t -s 30 /bin/echo aaa bbb ccc ddd a b
aaa bbb ccc ddd a b #length(/bin/echo aaa bbb ccc ddd a b )=30 $cat 1.txt |xargs -t -s 14 /bin/echo aaa
aaa
/bin/echo bbb
bbb
/bin/echo ccc
ccc
/bin/echo ddd
ddd
/bin/echo a b
a b #length(/bin/echo aaa )=14
-
-t
: 先打印执行的命令,然后执行
$cat 1.txt | xargs -t
/bin/echo aaa bbb ccc ddd a b
aaa bbb ccc ddd a b
-
-x
: 当xargs执行的命令长度大于-s max-char时,停止执行
-
-Pmax-procs
: 修改线程数,默认为单线程.max-procs为0时,as many processes as possible
/> ls -l -rw-r--r--. 1 root root 0 Nov 12 10:02 datafile3
-rw-r--r--. 1 root root 10530 Nov 11 23:08 test.tar.bz2
-rwxr--r--. 1 root root 183 Nov 11 08:02 users
-rw-r--r--. 1 root root 279 Nov 11 08:45 users2
#查找当前目录下的每一个普通文件,然后使用xargs命令来测试它们分别属于哪类文件。
/> find . -type f -print | xargs file ./users2: ASCII text
./datafile3: empty
./users: ASCII text
./test.tar.bz2: bzip2 compressed data, block size = 900k
#回收当前目录下所有普通文件的执行权限。
/> find . -type f -print | xargs chmod a-x /> ls -l -rw-r--r--. 1 root root 0 Nov 12 10:02 datafile3
-rw-r--r--. 1 root root 10530 Nov 11 23:08 test.tar.bz2
-rw-r--r--. 1 root root 183 Nov 11 08:02 users
-rw-r--r--. 1 root root 279 Nov 11 08:45 users2
#在当面目录下查找所有普通文件,并用grep命令在搜索到的文件中查找hostname这个词
/> find . -type f -print | xargs grep "hostname" #在整个系统中查找内存信息转储文件(core dump) ,然后把结果保存到/tmp/core.log 文件中。
/> find / -name "core" -print | xargs echo "" >/tmp/core.log /> pgrep MySQL | xargs kill -9 #直接杀掉mysql的进程
[1]+ Killed mysql
例子如下:
1. 当你尝试用rm 删除太多的文件,你可能得到一个错误信息:/bin/rm Argument list too long. 用xargs 去避免这个问题
find ~ -name ‘*.log' -print0 | xargs -0 rm -f
2. 获得/etc/ 下所有*.conf 结尾的文件列表,有几种不同的方法能得到相同的结果,下面的例子仅仅是示范怎么实用xargs ,在这个例子中实用 xargs将find 命令的输出传递给ls -l
# find /etc -name "*.conf" | xargs ls –l
3. 假如你有一个文件包含了很多你希望下载的URL, 你能够使用xargs 下载所有链接
# cat url-list.txt | xargs wget –c
4. 查找所有的jpg 文件,并且压缩它
# find / -name *.jpg -type f -print | xargs tar -cvzf images.tar.gz
5. 拷贝所有的图片文件到一个外部的硬盘驱动
# ls *.jpg | xargs -n1 -i cp {} /external-hard-drive/directory
EXAMPLES
find /tmp -name core -type f -print | xargs /bin/rm -f
Find files named core in or below the directory /tmp and delete them. Note that this will work incorrectly if there are any filenames containing newlines or spaces.
find /tmp -name core -type f -print0 | xargs -0 /bin/rm -f
Find files named core in or below the directory /tmp and delete them, processing filenames in such a way that file or directory names containing spaces or newlines are correctly handled.
find /tmp -depth -name core -type f -delete
Find files named core in or below the directory /tmp and delete them, but more efficiently than in the previous example (because we avoid the need to use fork(2) and exec(2) to launch rm and we don't need the extra xargs process).
cut -d: -f1 < /etc/passwd | sort | xargs echo
Generates a compact listing of all the users on the system.
xargs sh -c 'emacs "$@" < /dev/tty' emacs
Launches the minimum number of copies of Emacs needed, one after the other, to edit the files listed on xargs' standard input. This example achieves the same effect as BSD's -o option, but in a more flexible and portable way.
例如:
如果path目录下文件过多就会因为“参数列表过长”而报错无法执行。但改用xargs以后,问题即获解决。
find /path -type f -print0 | xargs -0 rm
xargs将find产生的长串文件列表拆散成多个子串,然后对每个子串调用rm。-print0表示输出以null分隔(-print使用换行);-0表示输入以null分隔。这样要比如下使用find命令效率高的多。
find /path -type f -exec rm '{}' \;
xargs命令应该紧跟在管道操作符之后,它以标准输入作为主要的源数据流,并使用stdin并通过提供命令行参数来执行其他命令,例如:
command | xargs
实例应用1,将多行输入转换为单行输出:
amosli@amosli-pc:~/learn$ cat example.txt
1 2 3 4 5
6 7
8
amosli@amosli-pc:~/learn$ cat example.txt | xargs
1 2 3 4 5 6 7 8
实例应用2,将单行输入转换为多行输出:
amosli@amosli-pc:~/learn$ cat example.txt | xargs -n 2
1 2
3 4
5 6
7 8
空格是默认的定界符,-n 表示每行显示几个参数
还可以使用-d参数来分隔参数,如下:
amosli@amosli-pc:~/learn$ echo "splitXhiXamosliXsplit" | xargs -d "X" -n 1
split
hi
amosli
split
实例应用3,读取stdin,将格式化参数传递给命令
#定义一个echo命令每次在输出参数后都加上#
amosli@amosli-pc:~/learn$ cat cecho.sh
echo $*'#'
#需求1:输出多个参数
amosli@amosli-pc:~/learn$ sh cecho.sh arg1
arg1#
amosli@amosli-pc:~/learn$ sh cecho.sh arg2
arg2#
amosli@amosli-pc:~/learn$ sh cecho.sh arg3
arg3#
#需求2:一次性提供所有的命令参数
amosli@amosli-pc:~/learn$ sh cecho.sh arg1 arg2 arg3
arg1 arg1 arg2 arg3#
#针对需求1、2,使用xargs代替,先用vi建一个新文件args.txt,如下:
amosli@amosli-pc:~/learn$ cat args.txt
arg1
arg2
arg3
#批量输出参数:
amosli@amosli-pc:~/learn$ cat args.txt | xargs -n 1
arg1
arg2
arg3
amosli@amosli-pc:~/learn$ cat args.txt | xargs -n 2 sh cecho.sh
arg1 arg2#
arg3#
#一次性输出所有参数:
amosli@amosli-pc:~/learn$ cat args.txt | xargs sh cecho.sh ;
arg1 arg2 arg3#
需求3,如何将参数嵌入到固定的命令行中?如下所示:
amosli@amosli-pc:~/learn$ sh cecho.sh -p args1 -1
-p args1 -1#
amosli@amosli-pc:~/learn$ sh cecho.sh -p args2 -1
-p args2 -1#
amosli@amosli-pc:~/learn$ sh cecho.sh -p args3 -1
-p args3 -1#
使用xargs的解决方案:
amosli@amosli-pc:~/learn$ cat args.txt | xargs -I {} sh cecho.sh -p {} -1
-p arg1 -1#
-p arg2 -1#
-p arg3 -1#
#-I {}批定了替换字符串,字符串{}会被从stdin读取到的参数所替换,使用-I时,能循环按要求替换相应的参数
实例应用4,结合find使用xargs
前面已经举过例子,这里要注意的是文件名称定界符要以字符null来分隔输出,如下所示,否则可能会误删文件
amosli@amosli-pc:~/learn$ find . -type f -name "*test*.txt" -print0 | xargs -0 rm -f
其他:
cat file | ( while read arg; do cat $arg; done )
cat file | xargs -I {} cat {}
当前题目:Linux-xargs命令
文章链接:
http://cqcxhl.cn/article/jescdp.html