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.


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.)


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

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' ' '

Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.