Eu estava confuso sobre o motivo pelo qual os diretórios podados também estavam sendo impressos pelo find
comando e alguns outros detalhes intricados de como -prune
funcionava, 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 -prune
seção das páginas de manual, conforme indicado na resposta do Timo , mas na EXPRESSIONS
seção:
Se a expressão não contiver ações além de -prune
,
-print
será executada em todos os arquivos para os quais a expressão é verdadeira.
o que significa que, como a expressão corresponde ao aa
nome do diretório, a expressão será avaliada como verdadeira e será impressa porque find adiciona implicitamente a -print
no final de todo o comando. No -print
entanto, ele não adicionará um se você propositadamente adicionar a ação -o -print
até 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 -print
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*
após -o
, você deve colocar a -print
no 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 -print
na segunda cláusula, como não há outra ação além da -prune
ação, o find adicionará um -print
automaticamente no fim do comando, fazendo com que a -prune
clá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 -print
comando 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 -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 para entender como -prune
funciona. A find
página de manual deve ser atualizada para evitar a confusão mundial sem fim sobre esse comando.
-print
, caso contrário, o implícito-print
se aplica a toda a condição