我试图使用该find
命令列出一组特定文件的大小,但没有得到任何输出。我使用的命令是:
find POD -type f -name *.mp3 -or -name *.ogg -ls
不会产生任何输出。尽管:
find POD -type f -name *.mp3 -or -name *.ogg
确实产生输出,我也尝试过以下操作:
-printf "%p %k KB\n"
-exec ls -ls '{}' \;
-print0
但所有这些都没有输出。当我以不同的表达方式使用这些操作中的任何一个时,例如:
find . -maxdepth 1 -type f -printf "%p %k KB\n"
我也得到了预期的输出。有人知道问题是什么吗?我在跑:
Linux irimi 3.10.37-1-MANJARO #1 SMP Mon Apr 14 20:56:29 UTC 2014 x86_64 GNU/Linux
又名最新的 Manjaro Linux 发行版。我使用的外壳是:/bin/bash
version 4.3.8(1)-release
。
SHELLOPTS
我的环境变量的内容是:
braceexpand:emacs:hashall:histexpand:history:interactive-comments:monitor
我的BASHOPTS
环境变量是:
cdspell:checkwinsize:cmdhist:complete_fullquote:dotglob:expand_aliases:extglob:extquote:force_fignore:histappend:hostcomplete:interactive_comments:nocaseglob:progcomp:promptvars:sourcepath
再次,我们将非常感谢任何有关尝试调试此问题的帮助。
答案1
有一个陷阱和/或上的关键字find
。or
适用于以下所有参数,包括操作(-ls
在您的示例中)。不带(或附加)and
的表达式按读取顺序进行计算,最后停止为 false。没有。or
and
implicit ()
所以这个命令的find POD -type f -name *.mp3 -or -name *.ogg -ls
意思是,
- 搜索(从 POD 目录开始)文件 --- 如果没有找到文件:停止
- else(找到文件)检查模式匹配
*.mp3
--- 如果模式匹配:停止! (因为OR
从这里应用并且仅当上一个命令失败时才应用(但仅是上一个命令,而不是之前的命令组)
并且因为您在命令行中添加了一条执行语句 ( -ls
, -exec
, -print
....) ,所以没有隐式-print
命令,因此如果 1) 1) 的所有条件都为真(文件和模式匹配),则无需执行任何操作。如果删除最后一个,则每个条件分支的末尾-ls
都会有一个隐式分布。-print
- 否则,如果模式不匹配,则搜索与该模式匹配的任何内容(文件/目录)
*.ogg
并列出它们(这-ls
不是条件命令,仅当前面的命令/测试“模式为真”时才会执行*.ogg
。但由于 1), 2) 仅针对非 mp3 文件进行评估,如果您没有.ogg
文件,则看不到任何内容。
解决方案1 在每个逻辑分支中重复执行命令
find POD -type f -name "*.mp3" -ls -or -name "*.ogg" -ls
解决方案2添加(受外壳保护的)括号
find POD -type f \( -name "*.mp3" -ls -or -name "*.ogg" \) -ls
笔记 您应该保护模式以避免当前目录中的 shell 模式评估。
答案2
我认为这是因为评估顺序(缺乏明确的优先级),例如如果
-name '*.mp3' -o -name '*.ogg' -ls
那么如果-name '*.ogg'
评估结果为 false,ls
则不执行该操作。您可以通过使用括号对 OR 表达式进行分组来获得您期望的行为 - 例如,如果
$ ls tests
file1.mp3 file2.mp3 file3.mp3
然后
$ find tests \( -name '*.mp3' -o -name '*.ogg' \) -print
tests/file3.mp3
tests/file1.mp3
tests/file2.mp3
然而
$ find tests -name '*.mp3' -o -name '*.ogg' -print
不产生输出。注意
$ find tests -name '*.mp3' -o -name '*.ogg'
是一种特殊情况,因为它被隐式地视为
$ find tests \( -name '*.mp3' -o -name '*.ogg' \) -print
还请注意,在命令中引用或转义 shell 全局变量是一种很好的做法,find
可以防止 shell 扩展它们 - 请参阅NON-BUGS
find 手册页的部分。