Mesclar resultados de dois comandos “find”

0

Gostaria de encontrar todos os diretórios que contêm ambos a Makefile e um arquivo correspondente a *.tex . O comando find ou locate encontra facilmente um ou outro. Mas como esses resultados podem ser mesclados ou interceptados, para produzir apenas os diretórios desejados?

Uma resposta útil generaliza para outros nomes de arquivos. Melhor ainda, pode mesclar mais de duas consultas.

(não vejo como aplicar os operadores booleanos de find , por exemplo, "e" expr1 -a expr2 . Idem para locate -A . Talvez duas pesquisas, descasque os nomes dos arquivos e mantenha os caminhos, sort -u , em comm -12 <(cmd1) <(cmd2) ?)

    
por Camille Goudeseune 29.05.2017 / 16:32

2 respostas

4

Use apenas -a para as condições 'AND':

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

Em câmera lenta:

  • -exec test -f {}/Makefile \; verifica se Makefile existe no diretório
  • -exec bash -c 'compgen -G '{}'/*.tex >/dev/null;exit $?' verifica se existem arquivos *.tex no diretório
  • a linha inteira testa a verdade apenas se ambos os testes forem verdadeiros
  • nesse caso, imprima o nome do diretório

Ran:

./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

Dá:

./no1/yes3
./yes1
./yes2
    
por 29.05.2017 / 17:40
1

find não pode fazer "subconsultas" para imprimir diretórios que contenham alguns arquivos, então comm é realmente o caminho a seguir:

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

Você também pode fazer um loop por diretórios (recursivamente com globstar ) que pode seja mais rápido ( compgen source ):

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

Tags