Usar
find \( -path "./tmp" -o -path "./scripts" \) -prune -o -name "*_peaks.bed" -print
ou
find \( -path "./tmp" -o -path "./scripts" \) -prune -false -o -name "*_peaks.bed"
ou
find \( -path "./tmp" -path "./scripts" \) ! -prune -o -name "*_peaks.bed"
A ordem é importante. Ele avalia da esquerda para a direita. Sempre comece com a exclusão do caminho.
Explicação
Não use -not
(ou !
) para excluir o diretório inteiro. Use -prune
. Conforme explicado no manual:
−prune The primary shall always evaluate as true; it
shall cause find not to descend the current
pathname if it is a directory. If the −depth
primary is specified, the −prune primary shall
have no effect.
e no manual de localização do GNU:
-path pattern
[...]
To ignore a whole
directory tree, use -prune rather than checking
every file in the tree.
Na verdade, se você usar -not -path "./pathname"
, find avaliará a expressão para cada nó em "./pathname"
.
encontrar expressões são apenas avaliações de condições.
\( \)
- operação de grupos (você pode usar -path "./tmp" -prune -o -path "./scripts" -prune -o
, mas é mais detalhado).
-path "./script" -prune
- se -path
retorna verdadeiro e é um diretório, retorna verdadeiro para aquele diretório e não desce para ele.
-path "./script" ! -prune
- avalia como (-path "./script") AND (! -prune)
. Ele reverte o "sempre verdadeiro" da poda para sempre falso. Isso evita a impressão "./script"
como um fósforo.
-path "./script" -prune -false
- como -prune
sempre retorna true, você pode seguir com -false
para fazer o mesmo que !
.
-o
- Operador OR. Se nenhum operador for especificado entre duas expressões, o padrão é o operador AND.
Portanto, \( -path "./tmp" -o -path "./scripts" \) -prune -o -name "*_peaks.bed" -print
é expandido para:
[ (-path "./tmp" OR -path "./script") AND -prune ] OR ( -name "*_peaks.bed" AND print )
A impressão é importante aqui porque sem ela é expandida para:
{ [ (-path "./tmp" OR -path "./script" ) AND -prune ] OR (-name "*_peaks.bed" ) } AND print
-print
é adicionado por find - é por isso que na maioria das vezes, você não precisa adicioná-lo em sua expressão. E como -prune
retorna true, ele irá imprimir "./script" e "./tmp".
Não é necessário nas outras porque mudamos -prune
para sempre retornar falso.
Dica: você pode usar find -D opt expr 2>&1 1>/dev/null
para ver como está otimizado e expandido,
find -D search expr 2>&1 1>/dev/null
para ver qual caminho está marcado.
_peaks.bed
.