Expansion de l'accolade de coquille de droite à gauche


9

Dans zsh (et autres shells), si j'inclus un argument comme (par exemple):

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

l'expansion de l'accolade le transforme en:

ad ae af bd be bf cd ce cf

Pour mes besoins, l'ordre des arguments est important, et j'ai besoin des accolades pour développer de droite à gauche au lieu de gauche à droite. Autrement dit, je veux que l'expansion soit:

ad bd cd ae be ce af bf cf

Existe-t-il un moyen de contrôler l'ordre dans lequel plusieurs jeux d'accolades sont développés? Je cherche quelque chose qui fonctionnera dans n'importe quelle situation, pas seulement avec ces arguments.


Je suppose que vous n'êtes pas intéressé par des solutions plus complexes impliquant des boucles ou une sortie triée, non?
terdon

@terdon S'il n'y a pas d'autre moyen, je suppose; J'espérais qu'il y avait une astuce pour changer l'ordre d'évaluation de l'expansion de l'accolade, mais il n'y en a probablement pas. Ces arguments n'étaient cependant qu'un exemple, donc quelque chose qui ne fonctionne que pour {a,b,c}{d,e,f}n'est pas très utile
Michael Mrozek

Ouais, j'ai deviné autant. Vous voudrez peut-être le préciser cependant pour éviter les réponses basées sur l'ordre de tri.
terdon

Réponses:


8

Vous pouvez combiner l'expansion des paramètres avec l'expansion des accolades.

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

Si vous ne souhaitez pas définir fooséparément (comme cela semble probable), vous pouvez utiliser ce qui suit:

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

Si l' rcexpandparamoption est définie, vous n'avez pas besoin de ^dans l'un ou l'autre exemple pour activer ce comportement.

(Remarque: lors des tests, j'ai également shwordsplitdéfini l' option. Si vous ne l'avez pas définie, essayez par exemple echo {a,b,c}${^=:-d e f}. Morale de l'histoire: presque tout est possible dans zsh, mais vous devez vous assurer que vous utilisez la bonne combinaison d'options et de syntaxe.)


1
Vous devez utiliser print -- {a,b,c}${^=:-d e f}comme exemple principal, car quand a split+globété désactivé par défaut dans zsh.
cuonglm

4

Dans, zshvous pouvez utiliser l' argument -C nombre de colonnes spécifié pour printaimer:

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

...obtenir...

ad bd cd ae be ce af bf cf

... sans le $IFSfractionnement des éléments suivants:

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

... impressions ...

ad bd cd
ae be ce
af bf cf

... mais vous pouvez le faire à travers avant vers le bas comme ...

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

Cela produit la même sortie que MIchael essaie d'éviter. Il veut 1.1 2.1 3.1 et vous donnez 1.1 1.2 1.3 (si c'est clair).
terdon

@terdon - bon point.
mikeserv

Je suppose (bien que cela ne soit pas explicitement indiqué) que Michael recherche l'ordre spécifique de couplage. Votre approche ne fonctionne que si les éléments peuvent être triés par ordre alphabétique. Que diriez-vous foobad foobaz barbad barbazd' obtenir de {foo, bar} {bad, baz} `?
terdon

@terdon - eh bien, si c'est ce qu'il recherche, pourquoi ne pas le dire? et de toute façon, les colonnes peuvent être appariées de n'importe quelle façon si vous faites le calcul.
mikeserv

1
@terdon - vous, les modérateurs, semblez prendre l'habitude de dire ce que vous ne voulez pas dire.
mikeserv

2

Vous pouvez mettre un nombre à la fin de chaque élément du deuxième ensemble, puis trier sur le dernier caractère:

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

Encore mieux serait d'ajouter des nombres après un séparateur (espace), de couper des champs, pas des caractères:

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

En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.