![查找包含多个相同扩展名的文件的目录](https://linux22.com/image/1446450/%E6%9F%A5%E6%89%BE%E5%8C%85%E5%90%AB%E5%A4%9A%E4%B8%AA%E7%9B%B8%E5%90%8C%E6%89%A9%E5%B1%95%E5%90%8D%E7%9A%84%E6%96%87%E4%BB%B6%E7%9A%84%E7%9B%AE%E5%BD%95.png)
我正在使用 Debian 8.0,例如,我想查找包含多个.mkv
文件的目录。我试过了,但失败了:
find -type d -exec find {} -name '*.mkv' | wc -l\;
有一个类似的SuperUser 上的问答,我无法适应。这也对我不起作用:
find . -maxdepth 1 -type d -exec bash -c "echo -ne '{} '; find '{}' -name '*.mkv' | wc -l" \; | awk '$NF>=2'
错误消息指向语法错误:
bash: -c: line 0: syntax error near unexpected token `('
原因是该目录有这样的名称:
Directory With Space and (Brackets)
答案1
我建议指示 find 查找所有文件并打印出每个匹配项的包含目录,这样您就不必担心解析奇怪的字符串。然后使用 uniq 计算重复项,打印出出现多次的重复项。例如
find . -type f -iname '*.mkv' -printf '%h\n' | sort | uniq -cd
编辑uniq -cd
按照 Scott 的建议替换 awk
答案2
我可能会尝试这样的事情:
find dirname -type f -name '*.mkv' -print0 | xargs -0 -L 1 dirname | sort | uniq -c | egrep -v '^ *1 ' | sed 's/^ *[0-9]* //'
find 输出所有 .mkv 文件的名称,然后 xargs 对所有内容执行 dirname 以仅提取目录名称,对所有条目进行排序,让 uniq 提供重复行数,并使用 egrep 删除那些只有 1 个 *.mkv 文件的行,最后使用 sed 删除计数以仅提供目录列表。
顺便说一句,使用 -print0 是为了使特殊字符文件名不会导致问题,在这种情况下,xargs 需要 -0 开关才能正确解释输入。正如评论中指出的那样,例外当然是文件名中的换行符,我个人没有遇到过。在这种情况下,xargs 需要 -0 开关才能正确解释输入。
答案3
有点像 hack,但这就是我要做的:
for dir in $(find . -type d)
do
if [ $(ls -l "$dir" | grep '\.mkv$' | wc -l) -ge 2 ]
then
echo "$dir"
fi
done
工作原理:
- 查找当前目录的所有子目录
find . -type d
并循环遍历它们,每个目录都保存在变量中dir
- 如果目录包含超过 2 个 mkv 文件,则打印
$dir
更新:
我的错,我忘了超过 2您的问题的一部分。应该使用-ge
而不是 来修复此问题-eq
(上面的问题已经修复)!
答案4
一个 perl 解决方案
perl -le 'use File::Find; find (sub {if(/\.mkv$/) {$d{$File::Find::dir}++}}, "."); END {for (sort keys %d) {print if $d{$_}>1}};'
此代码与其他代码类似。树遍历(当前目录“。”)在遇到 .mkv 文件(存储在 %d 哈希中)时会计算目录。遍历后,将打印出所有包含 2 个以上文件的目录。