查找操作不适用于特定搜索

查找操作不适用于特定搜索

我试图使用该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/bashversion 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

有一个陷阱和/或上的关键字findor适用于以下所有参数,包括操作(-ls在您的示例中)。不带(或附加)and的表达式按读取顺序进行计算,最后停止为 false。没有。orandimplicit ()

所以这个命令的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-BUGSfind 手册页的部分。

相关内容