Gerando parte aninhada de um padrão glob usando substituição de comando

Gerando parte aninhada de um padrão glob usando substituição de comando

Vamos começar com um exemplo simples de geração de nome de arquivo:

echo (xx|yy|zz)*.txt  # Example 1

Isto lista todos os arquivos txt começando com xx ou yy ou zz. Agora vamos gerar essas alternativas dinamicamente usando substituição de comandos; Estou usando echoaqui apenas para ilustrar para onde estou indo; em um exemplo do "mundo real", seria claro que seria algum programa:

echo $(echo '(xx|yy|zz)')*.txt  # Example 2

Isso funcionaria como acima. Agora vem a parte complicada: a substituição do comando deve fornecer apenas PARTE da lista de alternativas:

echo ($(echo 'xx|yy')|zz)*.txt  # Example 3 (does not work)

Isso não funcionaria mais: encontraria arquivos começando com zz, mas não aqueles com yy. Acho que Zsh está procurando arquivos começando literalmente xx|yyaqui.

Podemos fazê-lo funcionar se usarmos uma variável auxiliar:

list=$(echo 'xx|yy')
echo (${~list}|zz)*.txt   # Example 4

Agora a minha pergunta:

É possível obter o efeito do exemplo 4, sem utilizar uma variável temporária?

Responder1

Apenas use:

echo (${~"$(echo 'xx|yy')"}|zz)*.txt

Observe as aspas em torno da substituição do comando, pois zshrealiza a divisão de palavras, se não for globbing por padrão na substituição do comando, o que pode ser útil em coisas como:

echo (${~${(j:|:)$(cmd)}}).txt

para juntar as palavras na saída de cmdwith |e interpretá-las como um glob. Veja também o bsinalizador de expansão de parâmetro se não quiser que essas palavras sejam tratadas como padrões:

echo (${~${(j:|:)${(b)$(cmd)}}}).txt

informação relacionada