find -L . \
\( -type d \
\( -path "*/ignore" -o -path "*/indeed" -o \
\( -path "*/subdir/*" ! -path "*/subdir/save" \
\) \
\) \
\) \
-prune -o -print
Se você quiser um filtro extra (como -name "*.ext"
), você precisa colocar isso em branco antes de -print
. A última parte, em seguida, parece com isso
-prune -o \( -name "*.ext" \) -print
Note que alterei os nomes para facilitar a capacidade de escrita e a legibilidade. Nomes começando com i
devem ser ignorados. Nomes começando com s
devem ser mostrados. Nomes que terminam em file
são arquivos.
Minha árvore é assim:
$ find -printf "%y %p\n"
d .
d ./base
d ./base/subdir
d ./base/subdir/inform
f ./base/subdir/inform/imagefile
d ./base/subdir/isolate
f ./base/subdir/isolate/individualfile
f ./base/subdir/whatwhatinthefile
d ./base/subdir/save
f ./base/subdir/save/soundfile
f ./base/superfile
d ./base/indeed
f ./base/indeed/itemfile
d ./base/show
f ./base/show/startfile
d ./base/ignore
f ./base/ignore/importantfile
A saída do comando acima:
.
./base
./base/subdir
./base/subdir/whatwhatinthefile
./base/subdir/save
./base/subdir/save/soundfile
./base/superfile
./base/show
./base/show/startfile
Observe que whatwhatinthefile
em base/subdir
. Se você não quiser os arquivos em base/subdir
, precisará excluí-los explicitamente. Eu tentei, mas a linha de comando ficou feia demais.
Dependendo do seu caso de uso, pode ser mais fácil definir uma função de shell como esta:
contrivedfind() {
find -L . \
\( -type d \
\( -path "*/ignore" -o -path "*/indeed" -o -path "*/subdir" \
\) \
\) \
-prune -o -print
find -L ./base/subdir/save
}
A saída é agora:
.
./base
./base/superfile
./base/show
./base/show/startfile
./base/subdir/save
./base/subdir/save/soundfile
A única outra coisa diferente de antes agora é a entrada ./base/subdir
ausente. Mas acho que isso não importa no seu caso, porque você quer filtrar arquivos de qualquer maneira.
Como antes, você precisa colocar qualquer filtro extra antes do -print
no primeiro find
e desta vez também no final do segundo find
.