问题
在使用
find. / -name "*.txt*" | ls - l | awk - F " "'{ans+=$5}END{print ans}'
时,发现执行结果并不对......
又进行了如下尝试:
find ./ -name "*.txt*" | xargs ls -l | awk -F " " '{ans+=$5}END{print ans}'
find ./ -name "*.txt*" -exec ls -l {} \;| awk -F " " '{ans+=$5}END{print ans}'
发现若. txt 文件存在的情况下,两者执行结果相同,但如果. txt 文件不存在,xargs ls -l 返回的是当前目录列表,-exec ls -l {} \; 没有任何返回.
还有一种使用命令替换的方式:
ls - l`find. / -name "*.txt*"` | awk - F " "'{ans+=$5}END{print ans}'
执行结果与 xargs ls -l 相同.
问题来了:使用 | 管道,xargs,以及 find 中的 - exec 有啥区别?
一点知识
| 管道
将前一个命令的输出作为标准输入传给后面的命令,不会用到任何中间文件与缓冲区.
xargs
将前一个命令的输出作为命令行参数传给后面的命令.
由此可见,类似于 ls 这种只能读取命令行参数的命令,只能使用 xargs 来进行输出传递.
-exec
find 命令中 - exec 参数将查询结果通过命令行参数传递给后面的命令.
-exec 与 xargs 不同的是:-exec 是将结果逐条传递给后面的命令,后面的命令逐条执行.xargs 是将结果作为一个列表全部传递给后面的命令,后面的命令一次性执行参数串,可以通过 xargs -p ls -l 来查看即将要执行的完整的命令.
Tips:
目前已知的只能读取命令行参数的命令有:ls,rm.
通过分析 - exec 与 xargs 的不同,就会发现如果在 find 中使用 - exec+ls -lrt 的方式,列表并没有进行排序,若想要排序,可使用 xargs+ls -lrt
find ./ -name "*log*" -exec ls -lrt {} \; --rt无效
find ./ -name "*log*" | xargs ls -lrt --rt有效
参考文章
xargs 命令详解,xargs 与管道的区别 chapter 11. 构建基本脚本
来源: http://www.jianshu.com/p/a4272358d305