Espansione del controvento da destra a sinistra


9

In zsh (e altre shell), se includo un argomento come (ad esempio):

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

l'espansione del controvento lo trasforma in:

ad ae af bd be bf cd ce cf

Per i miei scopi, l'ordine degli argomenti è importante e ho bisogno che le parentesi graffe si espandano da destra a sinistra anziché da sinistra a destra. Cioè, voglio che l'espansione sia:

ad bd cd ae be ce af bf cf

C'è un modo per controllare l'ordine in cui vengono espansi più set di parentesi graffe? Sto cercando qualcosa che funzionerà in qualsiasi situazione, non solo con questi argomenti.


Suppongo che non ti interessino soluzioni più complesse che coinvolgono loop o output ordinati, giusto?
terdon

@terdon Se non c'è altro modo suppongo; Speravo ci fosse qualche trucco per cambiare l'ordine di valutazione dell'espansione del tutore, ma probabilmente non lo è. Questi argomenti erano solo un esempio, quindi qualcosa che funziona solo per {a,b,c}{d,e,f}non è molto utile
Michael Mrozek

Sì, ho indovinato tanto. Potresti voler chiarire questo per evitare risposte basate sull'ordinamento.
terdon

Risposte:


8

È possibile combinare l'espansione dei parametri con l'espansione del controvento.

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

Se non si desidera definire fooseparatamente (come sembra probabile), è possibile utilizzare quanto segue:

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

Se hai rcexpandparamimpostato l' opzione, non è necessario l' ^esempio in entrambi per abilitare questo comportamento.

(Nota: durante il test, ho anche shwordsplitimpostato l' opzione. Se non lo hai impostato, prova ad esempio echo {a,b,c}${^=:-d e f}. Morale della storia: quasi tutto è possibile in zsh, ma devi assicurarti di utilizzare il corretto combinazione di opzioni e sintassi.)


1
Dovresti usare print -- {a,b,c}${^=:-d e f}come esempio principale, da quando è split+globstato disattivato di default in zsh.
cuonglm,

4

In zshpuoi usare l' argomento -C numero specificato di colonne per printamare:

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

...ottenere...

ad bd cd ae be ce af bf cf

... senza la $IFSdivisione di quanto segue:

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

... stampe ...

ad bd cd
ae be ce
af bf cf

... ma puoi farlo attraverso prima giù come ...

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

Ciò produce lo stesso output che MIchael sta cercando di evitare. Vuole 1.1 2.1 3.1 e tu stai dando 1.1 1.2 1.3 (se è chiaro).
terdon

@terdon - buon punto.
mikeserv,

Immagino (anche se non esplicitamente dichiarato) che Michael sta seguendo l'ordine specifico di associazione. Il tuo approccio funziona solo se gli elementi possono essere ordinati alfabeticamente. Che dire di ottenere foobad foobaz barbad barbazda {foo, bar} {bad, baz} `?
terdon

@terdon - beh, se è quello che sta cercando allora perché non dirlo? e comunque, le colonne possono essere accoppiate in qualsiasi modo se si fa la matematica.
mikeserv,

1
@terdon - voi moderatori sembrate prendere l'abitudine di dire ciò che non intendete dire.
mikeserv,

2

Puoi mettere il numero alla fine di ogni elemento del secondo set e quindi ordinare l'ultimo carattere:

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

Ancora meglio sarebbe aggiungere numeri dopo qualche separatore (spazio), per tagliare campi, non caratteri:

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

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.