Eu estava confuso sobre por que os diretórios removidos estavam sendo impressos pelo comando find
também e alguns outros detalhes intrincados de como o -prune funcionava, mas foi capaz de descobrir isso com alguns exemplos.
Para executar os exemplos abaixo, crie os seguintes diretórios e arquivos.
mkdir aa
mkdir bb
touch file1
touch aa/file1
touch bb/file3
Agora use find para procurar diretórios chamados aa. Não tem problema aqui.
$ find . -type d -name aa
./aa
Procure por todos os diretórios que não sejam aa e obtemos o diretório atual. e ./bb que também faz sentido.
$ find . -type d ! -name aa
.
./bb
Até aí tudo bem, mas quando usamos -prune, find retorna o diretório que estamos removendo, o que inicialmente me confundiu porque eu esperava que ele retornasse todos os outros diretórios e não aquele que estava sendo podado.
$ find . -type d -name aa -prune
./aa
O motivo pelo qual ele retorna o diretório que está sendo limpo não é explicado na seção -prune
das páginas man, conforme indicado na resposta de Timo , mas na seção EXPRESSIONS
:
"If the expression contains no actions other than -prune, -print is
performed on all files for which the expression is true."
O que significa que, como a expressão corresponde ao nome do diretório aa
, a expressão será avaliada como true e será impressa porque o find na verdade adiciona uma impressão no final de todo o comando. No entanto, você não adicionará um -print
se propositadamente adicionar a ação -o -print
ao final:
find . -type d -name aa -prune -o -print
.
./file1
./bb
./bb/file3
Aqui, o comando "Localizar" NÃO adiciona mais uma impressão implícita e, portanto, o diretório que estamos removendo aa
não será impresso.
Então, finalmente, se adicionarmos uma cláusula que procura por arquivos com um padrão de nome de arquivo 'file *' depois do -o então você tem que colocar um -print no final dessa segunda cláusula assim:
find . \( -type d -name aa -prune \) -o \( -type f -name 'file*' -print \)
./file1
./bb/file3
A razão pela qual isso funciona é a mesma: se você não colocar uma -print na segunda cláusula, então, como não há nenhuma ação diferente da ação -prune, o find adicionará -print
automaticamente no THE END do comando fazendo com que a cláusula -prune
imprima o diretório limpo:
find . \( \( -type d -name aa -prune \) -o \( -type f -name 'file*' \) \) -print
./aa
./file1
./bb/file3
Em geral, você precisa colocar o comando -print na segunda cláusula. Se você colocá-lo no meio como fez o pôster original, ele não funcionará corretamente porque os arquivos que estão sendo removidos serão impressos imediatamente e a segunda cláusula não terá a chance de escolher os arquivos desejados:
find . \( -type d -name aa -prune -o -print \) -o \( -type f -name 'file*' \)
.
./file1
./bb
./bb/file3
Então, infelizmente, o pôster original errou o comando colocando o -print
no lugar errado. Pode ter funcionado para o seu caso específico, mas não funciona no caso geral.
Existem milhares de pessoas que têm dificuldades em entender como o -prune
funciona. stackoverflow.com/questions/4210042/exclude-directory-from-find-command/ 15736463 # 15736463 A página find
man deve ser atualizada para evitar a confusão mundial sem fim sobre este comando.