Расширение скобки справа налево

9

В zsh (и других оболочках), если я включу аргумент, например (например):

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

расширение скобки превращает это в:

ad ae af bd be bf cd ce cf

Для моих целей важен порядок аргументов, и мне нужно, чтобы фигурные скобки расширялись справа налево, а не слева направо. То есть я хочу, чтобы расширение было:

ad bd cd ae be ce af bf cf

Есть ли способ контролировать порядок расширения нескольких наборов скобок? Я ищу то, что будет работать в любой ситуации, а не только с этими аргументами.

Михаил Мрозек
источник
Полагаю, вас не интересуют более сложные решения, включающие циклы или отсортированный вывод, верно?
Terdon
@terdon Если нет другого пути, я полагаю; Я надеялся, что есть какая-то хитрость, чтобы изменить порядок оценки расширения скобок, но, вероятно, нет. Эти аргументы были только примером, поэтому то, что работает только на что-то, {a,b,c}{d,e,f}не очень полезно
Майкл Мрозек
Да, я так и предположил. Возможно, вы захотите прояснить это, чтобы избежать ответов, основанных на порядке сортировки.
Terdon

Ответы:

8

Вы можете комбинировать расширение параметров с расширением фигурных скобок.

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

Если вы не хотите определять fooотдельно (как представляется вероятным), вы можете использовать следующее:

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

Если у вас установлена rcexpandparamопция, вам не нужно ^ни в одном из примеров включать это поведение.

(Примечание: во время тестирования у меня также была установлена shwordsplitопция. Если она не установлена, попробуйте, например, echo {a,b,c}${^=:-d e f}Мораль истории: почти все возможно zsh, но вы должны убедиться, что используете правильный сочетание параметров и синтаксиса.)

chepner
источник
1
Вы должны использовать print -- {a,b,c}${^=:-d e f}в качестве основного примера, так как, когда split+globбыл выключен по умолчанию в zsh.
Cuonglm
4

В zshкачестве аргумента вы можете использовать -C указанное количество столбцовprint :

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

...получить...

ad bd cd ae be ce af bf cf

... без $IFSразделения на следующее:

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

... печать ...

ad bd cd
ae be ce
af bf cf

... но вы можете сделать это раньше, как вниз ...

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

ad ae af
bd be bf
cd ce cf

...или...

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

foobad foobaz barbad barbaz
mikeserv
источник
Это дает тот же результат, который пытается избежать Михаэль. Он хочет 1.1 2.1 3.1, а вы даете 1.1 1.2 1.3 (если это понятно).
Terdon
@terdon - хорошая мысль.
mikeserv
Я предполагаю (хотя явно не указано), что Майкл после определенного порядка спаривания. Ваш подход работает, только если элементы могут быть отсортированы по алфавиту. Как насчет получения foobad foobaz barbad barbazот {foo, bar} {bad, baz} `?
Тердон
@terdon - ну, если это то, что он после того, почему бы не сказать так? и в любом случае, столбцы могут быть объединены в любую сторону, если вы делаете математику.
mikeserv
1
@terdon - модераторы, кажется, привыкли говорить то, что не имеют в виду.
mikeserv
2

Вы можете поставить число в конце каждого элемента второго набора и затем отсортировать по последнему символу:

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

Еще лучше добавить числа после некоторого разделителя (пробела), чтобы вырезать поля, а не символы:

echo -e "\n"{a,b,c}{"d 1","e 2","f 3"} | sort -k 2n | cut -f 1 -d ' ' -s | tr '\n' ' '
jimmij
источник