合并两个“查找”命令的结果

合并两个“查找”命令的结果

我想找到所有包含的目录两个都aMakefile和 a 匹配的文件*.tex。命令findlocate很容易找到其中一个。但是如何合并或交叉这些结果,以产生所需的目录?

一个有用的答案可以推广到其他文件名。甚至更好的是,它可以合并两个以上的此类查询。

(我不知道如何应用的find布尔运算符,例如“and” expr1 -a expr2。对于也是如此locate -A。也许进行两次搜索,删除文件名并保留路径,,sort -u进入comm -12 <(cmd1) <(cmd2)?)

答案1

只需使用-a‘AND’条件:

find . -type d -exec test -f {}/Makefile \; -a -exec bash -c 'compgen -G '{}'/*.tex >/dev/null;exit $?' \; -print

慢动作:

  • -exec test -f {}/Makefile \;检查Makefile目录中是否存在
  • -exec bash -c 'compgen -G '{}'/*.tex >/dev/null;exit $?'*.tex检查目录中是否有任何文件
  • 仅当两个测试都为真时,整行测试才为真
  • 在这种情况下打印目录名称

跑在:

./no1
./no1/yes3
./no1/yes3/foo.tex
./no1/yes3/Makefile
./no1/no3
./no1/no
./no1/Makefile
./q
./no2
./no2/foo.tex
./yes1
./yes1/foo.tex
./yes1/Makefile
./yes2
./yes2/foo.tex
./yes2/Makefile

给出:

./no1/yes3
./yes1
./yes2

答案2

find无法执行“子查询”来打印包含某些文件的目录,因此comm确实是可行的方法:

comm -12 <(find . -name Makefile -exec dirname {} \; | sort ) <(find . -name '*.tex' -exec dirname {} \; | sort)

您还可以循环遍历目录(使用递归方式globstar)可能会更快(compgen来源):

for directory in */
do
    if [ -e "${directory}/Makefile" ] && compgen -G "${directory}/"*.tex > /dev/null
    then
        printf '%s\n' "${directory}"
    fi
done

相关内容