嘿,我有一个很大的目录树。我想找出所有包含文件的目录,文件名以“.ext1”结尾,文件名以“.ext2”结尾。
这怎么可能?我想过使用两个查找,一个用于“.ext1”,一个用于“.ext2”,但后来我需要找到交集,这怎么做?
谢谢!
这是一个相对简单的解决方案,find它只运行一次,将其输出存储在一个临时文件中,然后拆分并整理两个扩展名的结果。
tmp=$(mktemp)
find . -name '*.ext1' -o -name '*.ext2' | sort >"$tmp"
comm -12 <(<tmp sed -n 's!/[^/]*\.ext1$!!p' | sort) \
<(<tmp sed -n 's!/[^/]*\.ext2$!!p' | sort)
rm "$tmp"
Run Code Online (Sandbox Code Playgroud)
另一种方法是运行find以遍历目录并使用辅助程序来检查模式是否匹配。请注意,存在性检查在这种情况下有效,但如果您的搜索模式与自身不匹配并且是一个可能的文件名,则您需要更复杂的东西。
find . -type d -exec sh -c '{ set "$0"/*.ext1; [ -e "$1" ]; } &&
{ set "$0"/*.ext2; [ -e "$1" ]; }' {} \;
Run Code Online (Sandbox Code Playgroud)
这是一个 zsh 解决方案,其操作类似于最后一个命令:
echo **/*(/e\''set -- $REPLY/*.ext1(N[1]) $REPLY/*.ext2(N[1]); ((#==2))'\')
Run Code Online (Sandbox Code Playgroud)
这是另一个 zsh 解决方案,它*.ext1仅查找并选择具有*.ext2以下内容的目录:
echo ./**/*.ext1(e\''REPLY=${REPLY:h}; set -- $REPLY/*.ext2(N); ((#))'\')
Run Code Online (Sandbox Code Playgroud)
这是部分 Perl 解决方案;由于 Perl 的 globbing 的变迁,如果目录名称包含空格,它将不起作用(有办法解决这个问题,但我找不到一种远程优雅的方法)。
perl -l -MFile::Find -e \
'find {no_chdir => 1,
wanted => sub {<$_/*.ext1> and <$_/*.ext2> and print}}, "."'
Run Code Online (Sandbox Code Playgroud)