Eu estava confuso sobre o motivo pelo qual os diretórios podados também estavam sendo impressos pelo findcomando e alguns outros detalhes intricados de como -prunefuncionava, mas consegui 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
Para criar essa estrutura:
$ tree
.
├── aa
│ └── file1
├── bb
│ └── file3
└── file1
Agora use find para procurar diretórios nomeados 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, o que também faz sentido.
$ find . -type d ! -name aa
.
./bb
Até aqui 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 o que estava sendo podado.
$ find . -type d -name aa -prune
./aa
O motivo pelo qual ele retorna o diretório que está sendo removido é explicado, não na -pruneseção das páginas de manual, conforme indicado na resposta do Timo , mas na EXPRESSIONSseção:
Se a expressão não contiver ações além de -prune,
-printserá executada em todos os arquivos para os quais a expressão é verdadeira.
o que significa que, como a expressão corresponde ao aanome do diretório, a expressão será avaliada como verdadeira e será impressa porque find adiciona implicitamente a -printno final de todo o comando. No -printentanto, ele não adicionará um se você propositadamente adicionar a ação -o -printaté o fim:
find . -type d -name aa -prune -o -print
.
./file1
./bb
./bb/file3
Aqui, o comando find NÃO adiciona mais um implícito -printe, 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*após -o, você deve colocar a -printno final dessa segunda cláusula, como esta:
find . \( -type d -name aa -prune \) -o \( -type f -name 'file*' -print \)
./file1
./bb/file3
O motivo pelo qual isso funciona é o mesmo: se você não inserir um -printna segunda cláusula, como não há outra ação além da -pruneação, o find adicionará um -printautomaticamente no fim do comando, fazendo com que a -prunecláusula imprima o diretório removido:
find . \( \( -type d -name aa -prune \) -o \( -type f -name 'file*' \) \) -print
./aa
./file1
./bb/file3
Em geral, você precisa colocar o -printcomando na segunda cláusula. Se você colocá-lo no meio, como o pôster original, não funcionará corretamente, pois os arquivos que serão removidos serão impressos imediatamente e a segunda cláusula não terá a chance de escolher os arquivos que deseja:
find . \( -type d -name aa -prune -o -print \) -o \( -type f -name 'file*' \)
.
./file1
./bb
./bb/file3
Infelizmente, o pôster original entendeu errado o comando acima, colocando o -printno 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 para entender como -prunefunciona. A findpágina de manual deve ser atualizada para evitar a confusão mundial sem fim sobre esse comando.
-print, caso contrário, o implícito-printse aplica a toda a condição