Rozszerzanie nawiasów od prawej do lewej

9

W zsh (i innych powłokach), jeśli dołączę taki argument jak (na przykład):

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

Rozszerzenie nawiasów zamienia to w:

ad ae af bd be bf cd ce cf

Dla moich celów kolejność argumentów jest ważna i potrzebuję nawiasów klamrowych do rozwijania od prawej do lewej zamiast od lewej do prawej. To znaczy, chcę, aby rozszerzenie było:

ad bd cd ae be ce af bf cf

Czy istnieje sposób kontrolowania kolejności, w której wiele zestawów nawiasów klamrowych jest rozszerzanych? Szukam czegoś, co zadziała w każdej sytuacji, nie tylko z tymi argumentami.

Michał Mrożek
źródło
Zakładam, że nie interesują Cię bardziej złożone rozwiązania obejmujące pętle lub posortowane dane wyjściowe, prawda?
terdon
@terdon Jeśli nie ma innego sposobu, jak sądzę; Miałem nadzieję, że jest jakiś sposób na zmianę kolejności oceny rozszerzenia nawiasów, ale prawdopodobnie nie ma. Argumenty te były jednak tylko przykładem, więc coś, co działa tylko, {a,b,c}{d,e,f}nie jest zbyt pomocne
Michael Mrozek
Tak, chyba tak. Możesz jednak to wyjaśnić, aby uniknąć odpowiedzi na podstawie kolejności sortowania.
terdon

Odpowiedzi:

8

Można połączyć interpretację parametrów z interpretacją nawiasu.

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

Jeśli nie chcesz definiować fooosobno (co wydaje się prawdopodobne), możesz użyć następujących opcji:

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

Jeśli masz rcexpandparamustawioną opcję, nie potrzebujesz tej opcji ^w żadnym z przykładów, aby włączyć to zachowanie.

(Uwaga: podczas testowania miałem również shwordsplitopcję ustawioną. Jeśli jej nie masz, spróbuj na przykład echo {a,b,c}${^=:-d e f}. Morał z tej historii: prawie wszystko jest możliwe zsh, ale musisz upewnić się, że używasz właściwej połączenie opcji i składni.)

chepner
źródło
1
Powinieneś użyć print -- {a,b,c}${^=:-d e f}jako głównego przykładu, ponieważ kiedy split+globdomyślnie był wyłączony w zsh.
cuonglm,
4

W zshmożna użyć -C podanej liczby argumentów kolumny, aby printpolubić:

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

... żeby dostać ...

ad bd cd ae be ce af bf cf

... bez $IFSpodziału na następujące elementy:

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

... drukuje ...

ad bd cd
ae be ce
af bf cf

... ale możesz to zrobić wcześniej niż ...

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

ad ae af
bd be bf
cd ce cf

...lub...

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

foobad foobaz barbad barbaz
mikeserv
źródło
To daje taką samą wydajność, jakiej MIchael próbuje uniknąć. On chce 1.1 2.1 3.1, a ty dajesz 1.1 1.2 1.3 (jeśli to jasne).
terdon
@terdon - dobry punkt.
mikeserv
Zgaduję (choć nie wyraźnie), że Michael dąży do określonej kolejności parowania. Twoje podejście działa tylko wtedy, gdy elementy można sortować alfabetycznie. Co powiesz na uzyskanie foobad foobaz barbad barbazz {foo, bar} {bad, baz} `?
terdon
@terdon - cóż, jeśli to po to on, dlaczego by tego nie powiedzieć? w każdym razie kolumny można sparować w dowolny sposób, jeśli wykonasz matematykę.
mikeserv
1
@terdon - wy, moderatorzy, wydajecie się nawykiem mówienia tego, co nie macie na myśli.
mikeserv
2

Możesz umieścić liczbę na końcu każdego elementu drugiego zestawu, a następnie posortować według ostatniego znaku:

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

Jeszcze lepiej byłoby dodać liczby po pewnym separatorze (spacji), wyciąć pola, a nie znaki:

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