find结合xargs
管道是把一个命令的输出传递给另一个命令作为输入,比如:command1|command2但是command2仅仅把输出的内容当做字符串输入参数,
不能把它当做文件来处理。
xargs就是为了能够对find搜索到的文件进行操作而编写的。它能把管道传来的字符串当做文件交给其后的命令执行。
[root@localhost ~]# find /etc/ -name "hosts" | cat /etc/hosts [root@localhost ~]# find /etc/ -name "hosts" | xargs cat 127.0.0.1 localhost localhost.localdomain localhost4 localhost4.localdomain4 ::1 localhost localhost.localdomain localhost6 localhost6.localdomain6
注意:
在使用find命令的-exec选项处理匹配到的文件时,find命令将所有匹配到的文件一起传递给exec执行。但有些系统对能够传递给exec
的命令长度有限制,这样在find命令运行几分钟之后,就会出现溢出错误,错误信息通常是“参数列太长”或“参数列溢出”。这就是xrags
命令的用处所在,特别是与find命令一起使用。find命令把匹配到的文件传递给xargs命令,而xargs命令每次只获取一部分文件而不是
全部,不像-exec选项那样。这样它可以先处理最先获取的一部分文件,然后是下一批,并如此继续下去。
在有些系统中,使用-exec选项会为处理每一个匹配到的文件而发起一个相应的进程,并非将匹配到文件全部作为参数一次执行;这样有
些情况下就会出现进程过多,系统性能下降的问题。因而效率不高;而是用xargs命令则只有一个进程。另外,在使用xargs命令时,究竟
是一次获取所有的参数,还是分批获得参数,以及每一次获得参数的数码都会根据该命令的选项及系统内核中相应的可调参数来确定。
find | xrags command
对比xargs和-exec的区别
例1:验证执行方式
[root@localhost tmp]# touch {1..10}.txt [root@localhost tmp]# find -name "*.txt" -exec ls {} \; ./1.txt ./2.txt ./3.txt ./4.txt ./5.txt ./6.txt ./7.txt ./8.txt ./9.txt ./10.txt [root@localhost tmp]# find -name "*.txt" | xargs ls ./10.txt ./1.txt ./2.txt ./3.txt ./4.txt ./5.txt ./6.txt ./7.txt ./8.txt ./9.txt
例2:验证执行效率
[root@localhost tmp]# find . -name "*.txt" -exec rm {} \; [root@localhost tmp]# touch {1..100000}.txt [root@localhost ~]# find -name "*.txt" | xargs rm
xargs常用选项
//-0,当sdtin含有特殊字符时候,将其当成一般字符,像/空格符 [root@localhost ~]# touch "a b c.txt" [root@localhost ~]# find -name "*.txt" | xargs -0 ls ls: 无法访问./a b c.txt : 没有那个文件或目录 [root@localhost ~]# find -name "*.txt" -print0 | xargs -0 ls ./a b c.txt
//-a file 从文件中读入作为stdin [root@localhost ~]# cat >1.txt <<EOF > aaa bbb > ccc ddd > a s d er > EOF [root@localhost ~]# xargs -a 1.txt asdasasd asdasdasd asd
//-e flag,注意有的时候可能是-E,flag必须是一个以空格分隔的标志,当xargs分析道含有flag这个标志的时候就停止 [root@localhost ~]# xargs -E 'ddd' -a 1.txt aaa bbb ccc [root@localhost ~]# cat 1.txt | xargs -E 'ddd' aaa bbb ccc
//-n num后面加次数,表示命令在执行的时候一次用的argument的个数,默认是用所有的 [root@localhost ~]# cat 1.txt | xargs -n 2 aaa bbb ccc ddd a s d er
//-p 操作具有可交互性,每次执行command都交互式提示用户选择,当每次执行一个argument的时候询问一次用户 [root@localhost ~]# cat 1.txt | xargs -p echo aaa bbb ccc ddd a s d er ?...y aaa bbb ccc ddd a s d er
//-i 或者是-I,这得看linux支持了,将xargs的每项目名称,一般是一行一行赋值给{},可以用{}代替 [root@localhost ~]# touch {2..10}.txt #方法一 [root@localhost ~]# find -name "*.txt" | xargs -t cp -t /tmp/ #方法二 [root@localhost ~]# cp -v `find /root -name "*.txt"` /var/tmp/ [root@localhost ~]# cp $(find /root -name "*.txt") /var/tmp/ #方法三 [root@localhost ~]# find -name "*.txt" -exec cp {} /tmp \; #方法四 [root@localhost ~]# find -name "*.txt" | xargs -I {} cp -v {} /var/tmp/ "./a b c.txt" -> "/var/tmp/a b c.txt" "./1.txt" -> "/var/tmp/1.txt" "./2.txt" -> "/var/tmp/2.txt" "./3.txt" -> "/var/tmp/3.txt" "./4.txt" -> "/var/tmp/4.txt" "./5.txt" -> "/var/tmp/5.txt" "./6.txt" -> "/var/tmp/6.txt" "./7.txt" -> "/var/tmp/7.txt" "./8.txt" -> "/var/tmp/8.txt" "./9.txt" -> "/var/tmp/9.txt" "./10.txt" -> "/var/tmp/10.txt"