find -exec 与 find - xargs 的差别

最近我想统计下,家目录下各文件(夹)的硬盘占用情况,所以用了这个命令:
find -maxdepth 1 | xargs du -sh

返回的结果是,整个家目录的总大小,而不是预期的每个文件的大小。之后换用了find -maxdepth 1 -exec du -sh {} \;就能得出每个文件的大小。

为什么使用find | xargs得出的结果跟find -exec不一样呢?

一个问题是,我们为什么要使用xargs?xargs对find的标准输出做了什么处理?

以下面为例:

[lzx:~/.oh-my-zsh]¥ find -maxdepth 1 | xargs
. ./plugins ./templates ./.git ./README.textile ./oh-my-zsh.sh ./log ./.gitignore ./custom ./cache ./MIT-LICENSE.txt ./themes ./tools ./lib
[lzx:~/.oh-my-zsh]¥ find -maxdepth 1
.
./plugins
./templates
./.git
./README.textile
./oh-my-zsh.sh
./log
./.gitignore
./custom
./cache
./MIT-LICENSE.txt
./themes
./tools
./lib

默认情况下,xargs只是把\n转换成了空格。

所以find -maxdepth 1 | xargs du -sh
近似于:du -sh . ./plugins ./templates ./.git ./README.textile ./oh-my-zsh.sh ./log ./.gitignore ./custom ./cache ./MIT-LICENSE.txt ./themes ./tools ./lib
结果是6.8M,而不是独立计算每个文件夹的硬盘占用。

有趣的是,如果移除所有条目前面的./,得出的结果就是

du -s cache custom lib log MIT-LICENSE.txt oh-my-zsh.sh plugins README.textile templates themes tools .git .
924K cache
20K custom
72K lib
8.0K log
4.0K MIT-LICENSE.txt
4.0K oh-my-zsh.sh
2.0M plugins
8.0K README.textile
8.0K templates
572K themes
32K tools
3.2M .git
8.0K .

可见,使用find | xargsfind -exec之所以会得出不同的结果,du对命令行输入的处理方式也是原因之一。

再来看下find -exec是怎样的:
这里写了个argv.rb脚本,简单地输出命令行参数。

[lzx:~]¥ find ./code -exec ./argv.rb {} \;
["./code"]
["./code/test"]
["./code/test/package.json"]
["./code/test/public"]
["./code/test/public/javascripts"]
["./code/test/public/images"]
["./code/test/public/stylesheets"]
["./code/test/public/stylesheets/style.styl"]
["./code/test/public/stylesheets/style.css"]
["./code/test/views"]
["./code/test/views/user.ejs"]
["./code/test/views/index.ejs"]
["./code/test/views/error.ejs"]
["./code/test/models"]
["./code/test/models/User.js"]
...
[lzx:~]¥ find ./code | xargs ./argv.rb
["./code", "./code/test", "./code/test/package.json", "./code/test/public", "./code/test/public/javascripts", "./code/test/public/images", "./code/test/public/stylesheets", "./code/test/public/stylesheets/style.styl", "./code/test/public/stylesheets/style.css", "./code/test/views", "./code/test/views/user.ejs", "./code/test/views/index.ejs", "./code/test/views/error.ejs", "./code/test/models", "./code/test/models/User.js", ...]

可见find -exec是对每一个匹配的文件都执行了命令。

不过,如果不是以{} \;结尾({}会被替换成匹配的文件名),而是以{} +结尾,那么命令只会在最后执行一次。这类似于使用xargs的结果。

BTW,既然xargs只是简单地把\n变成空格,那么可能存在一些问题。比如文件名带空格,这时候xargs就给跪了。万一空格之后是-xx那样的内容,那就有得看了。当然通过指定\0作为分隔符,可以避免这种情况:

find . -maxdepth 1 -print0 | xargs -0 xxx

但是这么麻烦,还是坚持使用find . -exec xxx {} \;好了。

后记: 经别人指正,其实使用du -hd 1就能统计当前目录下各个文件(夹)占用的大小,无需使用find -maxdepth 1 -exec du -sh {} \;

### 回答1: 在Linux下,find命令可以用来查找文件和目录。在find命令的基础上,可以使用xargs-exec来进一步处理查找到的结果。 xargs命令可以将find命令查找到的结果作为参数传递给其他命令。例如,可以使用以下命令将查找到的所有文件删除: ``` find /path/to/dir -type f -name "*.txt" | xargs rm ``` 这个命令会查找/path/to/dir目录下所有扩展名为.txt的文件,并将它们作为参数传递给rm命令,从而删除这些文件。 -exec命令可以在find命令查找到的每个文件上执行指定的命令。例如,可以使用以下命令将查找到的所有文件复制到另一个目录: ``` find /path/to/dir -type f -name "*.txt" -exec cp {} /path/to/another/dir \; ``` 这个命令会查找/path/to/dir目录下所有扩展名为.txt的文件,并将它们复制到/path/to/another/dir目录中。 总的来说,xargs-exec命令可以帮助我们更方便地处理find命令查找到的结果。需要注意的是,使用这些命令时要注意参数的正确性和安全性。 ### 回答2: 在Linux系统中,find命令可以查找指定目录下的文件和文件夹,其语法如下所示: ```shell find path -options [expressions] ``` 其中,path表示要查找的目录路径,-options则是一系列选项,用于指定查找的规则,expressions则是查找表达式。 在find命令中,使用-xargs-exec选项可以在查找出符合条件的文件后执行相应操作。这两个选项的主要区别在于,-exec选项将查找到的文件作为参数传递给执行的命令,而-xargs选项则将它们作为标准输入流传递给命令。 举个例子,假设我们要查找当前目录下所有的.txt文件,并将它们全部重命名为_new.txt。我们可以使用以下命令: ```shell find . -name "*.txt" -exec mv {} {}_new.txt \; ``` 其中,-name选项用于指定查找的文件名模式,-exec选项则用于执行重命名操作,{}表示查找到的文件名,由于在命令行中{}是一个特殊的字符,因此需要使用\进行转义,最后一个分号表示命令的结束。 如果使用-xargs选项,我们需要将命令改为: ```shell find . -name "*.txt" | xargs -I {} mv {} {}_new.txt ``` 其中,|表示将find命令的输出作为xargs命令的输入,-I选项用于指定替换字符串(这里为{}),mv命令则将每个文件重命名为_new.txt。 需要注意的是,在使用-xargs选项时,对于包含空格等特殊字符的文件名,需要使用-0选项将它们用空字符分隔,如下所示: ```shell find . -name "*.txt" -print0 | xargs -0 -I {} mv {} {}_new.txt ``` 总的来说,使用-exec选项简单直观,而-xargs选项则更灵活,可以将查找到的文件批量传递给命令进行处理。因此,在实际运用中,我们可以根据具体情况选择合适的选项。 ### 回答3: 在Linux系统中,有两个常见的命令用于在文件系统中查找文件:findxargs。这两个命令可以用来找到符合特定条件的文件,但是它们的功能略有不同。 find命令是一个非常强大的工具,它可以用来查找任意目录下符合指定条件的文件或目录。find命令的语法为: find [path] [expression] 其中path表示要查找的目录或文件,而expression是由各种测试和动作组成的语句。 xargs命令则是用来接收一个命令的输出作为输入,并将其传递给另一个命令。xargs命令的常见用法是将find命令的输出作为xargs的输入,并将输出交给另一个命令来处理。 在使用find命令和xargs命令时,有两种常见的用法。第一种是使用find命令和-exec选项来执行一个命令,第二种是使用find命令和xargs命令来其他工具一起使用。 使用find命令和-exec选项来执行命令 在使用find命令时,最常见的选项是-exec。该选项允许您执行一个命令,以处理每个find找到的文件。下面是一个示例: find /home -name "*.txt" -exec cat {} \; 此命令将在/home目录下查找所有扩展名为.txt的文件,并将它们的内容输出到终端。 使用find命令和xargs命令其他工具一起使用 find命令的输出可以用作xargs命令的输入。在这种情况下,xargs命令将用每个换行符分隔的输出作为参数,并将其传递给指定的命令。以下示例演示了这种用途: find /home -name "*.txt" | xargs grep "keyword" 此命令将在/home目录下查找所有扩展名为.txt的文件,并将它们的内容传递给grep命令以查找关键字。 总之,find命令和xargs命令都是Linux系统中常用的工具,可以用于查找文件和将一组文件传递给其他命令进行处理。使用它们可以简化许多常见的任务,并增强您在Linux系统中的生产力。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值