Expansão da chave da concha da direita para a esquerda

9

No zsh (e em outros shells), se eu incluir um argumento como (por exemplo):

{a,b,c}{d,e,f}

expansão chave transforma em:

ad ae af bd be bf cd ce cf

Para meus propósitos, a ordem dos argumentos é importante e preciso que os colchetes se expandam da direita para a esquerda em vez de da esquerda para a direita. Ou seja, eu quero que a expansão seja:

ad bd cd ae be ce af bf cf

Existe uma maneira de controlar a ordem em que vários conjuntos de chaves são expandidos? Estou procurando algo que funcione em qualquer situação, não apenas com esses argumentos.

Michael Mrozek
fonte
Suponho que você não esteja interessado em soluções mais complexas que envolvam loops ou saída classificada, certo?
terdon
@terdon Se não houver outra maneira, suponho; Eu esperava que houvesse algum truque para alterar a ordem de avaliação da expansão da cinta, mas provavelmente não existe. Estes argumentos foram apenas um exemplo, porém, assim algo que só funciona para {a,b,c}{d,e,f}não é muito útil
Michael Mrozek
Sim, eu adivinhei. Você pode deixar isso claro, para evitar respostas com base na ordem de classificação.
terdon

Respostas:

8

Você pode combinar a expansão de parâmetros com a expansão de chaves.

% foo=(d e f)
$ echo {a,b,c}${^foo}
ad bd cd ae be ce af bf cf

Se você não deseja definir fooseparadamente (como parece provável), pode usar o seguinte:

$ echo {a,b,c}${^:-d e f}
ad bd cd ae be ce af bf cf

Se você tiver a rcexpandparamopção definida, não precisará do ^exemplo para ativar esse comportamento.

(Nota: durante o teste, eu também tive a shwordsplitopção definida. Se você não a tiver definido, tente, por exemplo echo {a,b,c}${^=:-d e f}. Moral da história: quase tudo é possível zsh, mas você precisa se certificar de que está usando o método correto. combinação de opções e sintaxe.)

chepner
fonte
1
Você deve usar print -- {a,b,c}${^=:-d e f}como exemplo principal, pois quando split+globfoi desativado por padrão em zsh.
cuonglm
4

Em zshvocê pode usar o -C número especificado de argumentos de colunas para printgostar:

print $(print -C3 {a,b,c}{d,e,f})

...para obter...

ad bd cd ae be ce af bf cf

... sem $IFSdividir o seguinte:

print -C3 {a,b,c}{d,e,f}

... imprime ...

ad bd cd
ae be ce
af bf cf

... mas você pode fazer isso do outro lado antes para baixo como ...

print -aC3 {a,b,c}{d,e,f}

ad ae af
bd be bf
cd ce cf

...ou...

print $(print -aC2 {foo,bar}{bad,baz})

foobad foobaz barbad barbaz
mikeserv
fonte
Isso produz a mesma saída que o MIchael está tentando evitar. Ele quer 1.1 2.1 3.1 e você está dando 1.1 1.2 1.3 (se estiver claro).
terdon
@terdon - bom ponto.
mikeserv
Estou supondo (embora não esteja explicitamente declarado) que Michael esteja seguindo a ordem específica de emparelhamento. Sua abordagem só funciona se os elementos puderem ser classificados em ordem alfabética. Que tal sair foobad foobaz barbad barbazde {foo, bar} {bad, baz} `?
terdon
@terdon - bem, se é isso que ele procura, por que não dizê-lo? de qualquer maneira, as colunas podem ser emparelhadas de qualquer maneira, se você fizer as contas.
mikeserv
1
@terdon - vocês moderadores parecem criar o hábito de dizer o que você não quer dizer.
mikeserv
2

Você pode colocar o número no final de cada elemento do segundo conjunto e classificar o último caractere:

echo -e "\n"{a,b,c}{d1,e2,f3} | sort -k 1.3 | cut -c 1-2 | tr '\n' ' '

Melhor ainda seria adicionar números após um separador (espaço), cortar campos, não caracteres:

echo -e "\n"{a,b,c}{"d 1","e 2","f 3"} | sort -k 2n | cut -f 1 -d ' ' -s | tr '\n' ' '
jimmij
fonte