Розширення підтяжки справа наліво наліво


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 Якщо я думаю, немає іншого способу; Я сподівався, що існує якийсь хитрість змінити порядок оцінки розширення брекетів, але, мабуть, цього немає. Ці аргументи були лише прикладом, тому щось, на що працює лише {a,b,c}{d,e,f}, не дуже допомагає
Michael Mrozek

Так, я здогадався стільки ж. Можливо, ви хочете зробити це зрозумілим, щоб уникнути відповідей на основі порядку сортування.
тердон

Відповіді:


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, але ви повинні переконатися, що ви використовуєте правильний поєднання параметрів та синтаксису.)


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

Це дає той самий вихід, який намагається уникати MIchael. Він хоче 1.1 2.1 3.1, а ви даєте 1.1 1.2 1.3 (якщо це зрозуміло).
тердон

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

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.