Expansión de abrazadera de concha de derecha a izquierda


9

En zsh (y otros shells), si incluyo un argumento como (por ejemplo):

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

la expansión de llaves lo convierte en:

ad ae af bd be bf cd ce cf

Para mis propósitos, el orden de los argumentos es importante, y necesito las llaves para expandir de derecha a izquierda en lugar de izquierda a derecha. Es decir, quiero que la expansión sea:

ad bd cd ae be ce af bf cf

¿Hay alguna manera de controlar el orden en que se expanden múltiples conjuntos de llaves? Estoy buscando algo que funcione en cualquier situación, no solo con estos argumentos.


Supongo que no está interesado en soluciones más complejas que involucren bucles o salida ordenada, ¿verdad?
terdon

@terdon Si no hay otra forma, supongo; Esperaba que hubiera algún truco para cambiar el orden de evaluación de la expansión del aparato ortopédico, pero probablemente no lo haya. Sin embargo, esos argumentos fueron solo un ejemplo, por lo que algo que solo funciona {a,b,c}{d,e,f}no es muy útil
Michael Mrozek

Sí, ya lo adiviné. Sin embargo, es posible que desee aclarar eso para evitar respuestas basadas en el orden de clasificación.
terdon

Respuestas:


8

Puede combinar la expansión de parámetros con la expansión de llaves.

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

Si no desea definir por fooseparado (como parece probable), puede usar lo siguiente:

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

Si tiene rcexpandparamconfigurada la opción, no necesita ^en ninguno de los ejemplos para habilitar este comportamiento.

(Nota: durante la prueba, también tuve la shwordsplitopción configurada. Si no la tiene configurada, intente, por ejemplo echo {a,b,c}${^=:-d e f}. Moraleja de la historia: casi todo es posible zsh, pero debe asegurarse de estar utilizando la correcta combinación de opciones y sintaxis.)


1
Debe usar print -- {a,b,c}${^=:-d e f}como ejemplo principal, ya que cuando split+globestaba desactivado por defecto en zsh.
Cuonglm

4

En zshpuede utilizar el argumento -C de número de columnas especificado para printgustar:

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

...Llegar...

ad bd cd ae be ce af bf cf

... sin $IFSdividir lo siguiente:

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

...huellas dactilares...

ad bd cd
ae be ce
af bf cf

... pero puedes hacer eso antes de abajo como ...

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

ad ae af
bd be bf
cd ce cf

...o...

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

foobad foobaz barbad barbaz

Eso produce el mismo resultado que MIchael está tratando de evitar. Él quiere 1.1 2.1 3.1 y le está dando 1.1 1.2 1.3 (si está claro).
terdon

@terdon - buen punto.
mikeserv

Supongo (aunque no se dice explícitamente) que Michael está siguiendo el orden específico de emparejamiento. Su enfoque solo funciona si los elementos se pueden ordenar alfabéticamente. ¿Qué pasa foobad foobaz barbad barbazcon {foo, bar} {bad, baz} `?
terdon

@terdon - bueno, si eso es lo que busca, ¿por qué no decirlo? y de todos modos, las columnas se pueden emparejar de cualquier manera si haces los cálculos.
mikeserv

1
@terdon - ustedes moderadores parecen acostumbrarse a decir lo que no quieren decir.
mikeserv

2

Puede poner un número al final de cada elemento del segundo conjunto y luego ordenar el último carácter:

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

Aún mejor sería agregar números después de un separador (espacio), para cortar campos, no caracteres:

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

Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.