O comando find: as opções '-mindepth' conflitam com a ação '-prune'

6

Se a estrutura do arquivo for assim:

/a/p/c/d...
/c/a/c/g/f/...
/a/c/d/e/...
...

E eu quero fazer isso:

find -mindepth 3 -type d -name p -prune -or -name c -print

No entanto, este comando não irá remover o diretório 'p' e a primeira linha será incluída. Eu sei que na verdade não é um conflito. Mas como podar 'p' com o mindepth aplicado?

    
por Bohr 03.06.2013 / 08:35

3 respostas

1

Acho que eu faria assim:

find -mindepth 3 -type d ! -path '*/p/*' -name c -print

Com base no feedback de @StephaneChazelas, acredito que esse método eliminaria a pesquisa externa em qualquer diretório /p/ :

find -mindepth 3 -type d -path '*/p/*' -prune -o -name c -print

Analisando uma descoberta

Para comparar os comandos de localização, você pode adicionar a opção de depuração -D search , para que você possa ver o desempenho de uma determinada descoberta em relação a outra.

Corri o comando do @StephaneChazelas contra o meu para ver onde estavam as diferenças. Os dois comandos são executados e sua saída é executada em sdiff abaixo:

$ sdiff \
<(find -D search -mindepth 3 -type d -path '*/p/*' -prune -o -name c -print 2>&1) \
<(find -D search -type d -name p -prune -o -path './*/*/*' -name c -print 2>&1)
consider_visiting (early): '.': fts_info=FTS_D , fts_level= 0   consider_visiting (early): '.': fts_info=FTS_D , fts_level= 0
consider_visiting (late): '.': fts_info=FTS_D , isdir=1 ignor | consider_visiting (late): '.': fts_info=FTS_D , isdir=1 ignor
consider_visiting (early): './a': fts_info=FTS_D , fts_level=   consider_visiting (early): './a': fts_info=FTS_D , fts_level=
consider_visiting (late): './a': fts_info=FTS_D , isdir=1 ign | consider_visiting (late): './a': fts_info=FTS_D , isdir=1 ign
consider_visiting (early): './a/c': fts_info=FTS_D , fts_leve   consider_visiting (early): './a/c': fts_info=FTS_D , fts_leve
consider_visiting (late): './a/c': fts_info=FTS_D , isdir=1 i | consider_visiting (late): './a/c': fts_info=FTS_D , isdir=1 i
consider_visiting (early): './a/c/d': fts_info=FTS_D , fts_le   consider_visiting (early): './a/c/d': fts_info=FTS_D , fts_le
consider_visiting (late): './a/c/d': fts_info=FTS_D , isdir=1   consider_visiting (late): './a/c/d': fts_info=FTS_D , isdir=1
consider_visiting (early): './a/c/d/e': fts_info=FTS_D , fts_   consider_visiting (early): './a/c/d/e': fts_info=FTS_D , fts_
consider_visiting (late): './a/c/d/e': fts_info=FTS_D , isdir   consider_visiting (late): './a/c/d/e': fts_info=FTS_D , isdir
consider_visiting (early): './a/c/d/e': fts_info=FTS_DP, fts_   consider_visiting (early): './a/c/d/e': fts_info=FTS_DP, fts_
consider_visiting (late): './a/c/d/e': fts_info=FTS_DP, isdir   consider_visiting (late): './a/c/d/e': fts_info=FTS_DP, isdir
consider_visiting (early): './a/c/d': fts_info=FTS_DP, fts_le   consider_visiting (early): './a/c/d': fts_info=FTS_DP, fts_le
consider_visiting (late): './a/c/d': fts_info=FTS_DP, isdir=1   consider_visiting (late): './a/c/d': fts_info=FTS_DP, isdir=1
consider_visiting (early): './a/c': fts_info=FTS_DP, fts_leve   consider_visiting (early): './a/c': fts_info=FTS_DP, fts_leve
consider_visiting (late): './a/c': fts_info=FTS_DP, isdir=1 i   consider_visiting (late): './a/c': fts_info=FTS_DP, isdir=1 i
consider_visiting (early): './a/p': fts_info=FTS_D , fts_leve   consider_visiting (early): './a/p': fts_info=FTS_D , fts_leve
consider_visiting (late): './a/p': fts_info=FTS_D , isdir=1 i | consider_visiting (late): './a/p': fts_info=FTS_D , isdir=1 i
consider_visiting (early): './a/p/c': fts_info=FTS_D , fts_le | consider_visiting (early): './a/p': fts_info=FTS_DP, fts_leve
consider_visiting (late): './a/p/c': fts_info=FTS_D , isdir=1 <
consider_visiting (early): './a/p/c': fts_info=FTS_DP, fts_le <
consider_visiting (late): './a/p/c': fts_info=FTS_DP, isdir=1 <
consider_visiting (early): './a/p': fts_info=FTS_DP, fts_leve <
consider_visiting (late): './a/p': fts_info=FTS_DP, isdir=1 i   consider_visiting (late): './a/p': fts_info=FTS_DP, isdir=1 i
consider_visiting (early): './a': fts_info=FTS_DP, fts_level=   consider_visiting (early): './a': fts_info=FTS_DP, fts_level=
consider_visiting (late): './a': fts_info=FTS_DP, isdir=1 ign   consider_visiting (late): './a': fts_info=FTS_DP, isdir=1 ign
consider_visiting (early): './c': fts_info=FTS_D , fts_level=   consider_visiting (early): './c': fts_info=FTS_D , fts_level=
consider_visiting (late): './c': fts_info=FTS_D , isdir=1 ign | consider_visiting (late): './c': fts_info=FTS_D , isdir=1 ign
consider_visiting (early): './c/a': fts_info=FTS_D , fts_leve   consider_visiting (early): './c/a': fts_info=FTS_D , fts_leve
consider_visiting (late): './c/a': fts_info=FTS_D , isdir=1 i | consider_visiting (late): './c/a': fts_info=FTS_D , isdir=1 i
consider_visiting (early): './c/a/c': fts_info=FTS_D , fts_le   consider_visiting (early): './c/a/c': fts_info=FTS_D , fts_le
consider_visiting (late): './c/a/c': fts_info=FTS_D , isdir=1   consider_visiting (late): './c/a/c': fts_info=FTS_D , isdir=1
consider_visiting (early): './c/a/c/g': fts_info=FTS_D , fts_   consider_visiting (early): './c/a/c/g': fts_info=FTS_D , fts_
consider_visiting (late): './c/a/c/g': fts_info=FTS_D , isdir   consider_visiting (late): './c/a/c/g': fts_info=FTS_D , isdir
consider_visiting (early): './c/a/c/g/f': fts_info=FTS_D , ft   consider_visiting (early): './c/a/c/g/f': fts_info=FTS_D , ft
consider_visiting (late): './c/a/c/g/f': fts_info=FTS_D , isd   consider_visiting (late): './c/a/c/g/f': fts_info=FTS_D , isd
consider_visiting (early): './c/a/c/g/f': fts_info=FTS_DP, ft   consider_visiting (early): './c/a/c/g/f': fts_info=FTS_DP, ft
consider_visiting (late): './c/a/c/g/f': fts_info=FTS_DP, isd   consider_visiting (late): './c/a/c/g/f': fts_info=FTS_DP, isd
consider_visiting (early): './c/a/c/g': fts_info=FTS_DP, fts_   consider_visiting (early): './c/a/c/g': fts_info=FTS_DP, fts_
consider_visiting (late): './c/a/c/g': fts_info=FTS_DP, isdir   consider_visiting (late): './c/a/c/g': fts_info=FTS_DP, isdir
consider_visiting (early): './c/a/c': fts_info=FTS_DP, fts_le   consider_visiting (early): './c/a/c': fts_info=FTS_DP, fts_le
consider_visiting (late): './c/a/c': fts_info=FTS_DP, isdir=1   consider_visiting (late): './c/a/c': fts_info=FTS_DP, isdir=1
consider_visiting (early): './c/a': fts_info=FTS_DP, fts_leve   consider_visiting (early): './c/a': fts_info=FTS_DP, fts_leve
consider_visiting (late): './c/a': fts_info=FTS_DP, isdir=1 i   consider_visiting (late): './c/a': fts_info=FTS_DP, isdir=1 i
consider_visiting (early): './c': fts_info=FTS_DP, fts_level=   consider_visiting (early): './c': fts_info=FTS_DP, fts_level=
consider_visiting (late): './c': fts_info=FTS_DP, isdir=1 ign   consider_visiting (late): './c': fts_info=FTS_DP, isdir=1 ign
consider_visiting (early): '.': fts_info=FTS_DP, fts_level= 0   consider_visiting (early): '.': fts_info=FTS_DP, fts_level= 0
consider_visiting (late): '.': fts_info=FTS_DP, isdir=1 ignor   consider_visiting (late): '.': fts_info=FTS_DP, isdir=1 ignor
./c/a/c                             ./c/a/c

Se você notar, há uma lacuna na abordagem de Stephane que a minha não tem. Mesmo com a ameixa. Eu acho que isso mostra que seu método é evitar trabalho extra ao entrar em diretórios que, de outra forma, deveria estar ignorando.

    
por 03.06.2013 / 09:16
3

Com o FreeBSD e o GNU find (que são algumas das poucas implementações que suportam -mindepth ), seu -prune apenas podaria os diretórios p que estão na profundidade 3 ou mais profunda. Tanto a documentação do FreeBSD quanto a do GNU find deixam bem claro (aqui a documentação do GNU):

-- Option: -mindepth levels
    Do not apply any tests or actions at levels less than LEVELS (a
    non-negative integer).  '-mindepth 1' means process all files
    except the command line arguments.

Você sempre pode fazer isso da maneira padrão:

find . -type d -name p -prune -o -path './*/*/*' -name c -print

( -mindepth e -or não são predicados padrão find , omitindo o (s) diretório (s) também não é padrão).

Ou com zsh :

setopt extendedglob
printf '%s\n' ^p/^p/(^p/)#c
    
por 03.06.2013 / 09:14
0

De acordo com a página man do find:

 -prune True;  if  the  file is a directory, do not descend into it. If
        -depth is given, false; no  effect.

Então, no seu caso particular, eu faria algo como:

 find a/* -mindepth 2  -type f -print

Mas é claro que nem sempre existe uma solução tão fácil.

    
por 03.06.2013 / 08:56

Tags