É um padrão zh extended glob. O objetivo é combinar todos os arquivos com um padrão em uma hierarquia de diretórios, com exceção de sub-hierarquias específicas. O padrão no título funciona, mas eu queria algo que não exigisse a repetição de long/path/
.
Eu tentei o seguinte:
long/path/(^(bad-1|bad-2)/|)**/^*.(complex|pattern)(.)
long/path/(**~(bad-1|bad-2)/*)/^*.(complex|pattern)(.)
com KSH_GLOB
adicionado:
long/path/?(^(bad-1|bad-2)/)**/^*.(complex|pattern)(.)
Todos eles resultam em um erro de padrão ruim. Parece que o problema é ter um /
entre parênteses. A documentação diz:
As mentioned above, a '/' used as a directory separator may not appear inside parentheses
Isso me confundiu porque (dir/)#
é um bom padrão. Ele é mencionado nos documentos:
A pathname component of the form '(foo/)#' matches a path consisting of zero or more directories matching the pattern foo.
Eu acho que é a exceção.
Para ser claro, estou procurando por equivalentes. Isso exclui:
long/path/^(bad-1|bad-2)/**/^*.(complex|pattern)(.)
pois exclui itens como long/path/good.pattern
e
long/path/(^(bad-1|bad-2)/)#/^*.(complex|pattern)(.)
long/path/**/^*.(complex|pattern)~*/(bad-1|bad-2)/*(.)
desde que aqueles excluam coisas como o que está abaixo de long/path/good/bad-1
.
EDIT: Só para mencionar, uma solução não precisa necessariamente usar apenas globbing. Se isso puder ser feito adicionando o uso de chave ou expansão de histórico ou algum outro recurso zsh, isso é ótimo.
EDIT 2: Seguindo minhas próprias idéias, tentei expandir a história:
long/path/**/^*.(complex|pattern)~!{#$:s/\**//}/(bad-1|bad-2)/*(.)
No entanto, isso falhou porque 1) a última palavra da linha atual é a anterior àquela em que a expansão está, e 2) porque a substituição da história parece ser feita após a expansão glob (devo estar entendendo mal alguma coisa aqui porque isso parece ir contra os documentos; talvez todas as expansões sejam feitas com base em palavras por palavra).
Eu também tentei a expansão de chaves:
( IFS=\~; printf "%s\n" long/path/{**/^*.(complex|pattern),(bad-1|bad-2)/*(.)} )
Não funcionou. Os dois padrões globais ainda eram tomados como palavras separadas, em vez de serem unidos em um único padrão. Eu acho que IFS
não é levado em consideração aqui. Faz sentido.
Eu também tentei substituição em qualificadores glob:
+/**/^*.(complex|pattern)~+/(bad-1|bad-2)/*(.:s,+,long/path,)
Mas, é claro, isso não funcionaria porque a substituição seria feita depois da correspondência, não antes.