2016-03-17 2 views
4

Предположим, что я вызываю сценарий с тремя аргументами, a, и xyz такими, что [email protected] содержит эти три аргумента.

Предположим, я хочу назвать написать команду:

command fooa fooabc fooxyz bara barabc barxyz 

Как бы я выполнить это?

Не думаю, что {foo,bar}[email protected] или {foo,bar}{[email protected]} Работа с расширением брекета происходит до [email protected].

+0

В zsh, '{foo, bar}" $ @ "' действительно работает таким образом. К сожалению, не в bash. – Kevin

+0

@ Кевин почти. Это расширяется до 'fooa bara fooabc barabc fooxyz barxyz'. – chepner

+0

@chepner Я думаю, если порядок имеет значение для этой конкретной команды ... – Kevin

ответ

8

Вы можете использовать:

command "${@/#/foo}" "${@/#/bar}" 

Это использует вариант заменителя shell parameter expansion. # привязывает совпадение к началу параметра.

$ set -- a abc xyz 
$ echo command "${@/#/foo}" "${@/#/bar}" 
command fooa fooabc fooxyz bara barabc barxyz 
$ 

Есть ли способ масштабирования это для увеличения {foo,bar,baz,...}[email protected] или {foo,bar}{123,456}[email protected]?

Да, но вы в конечном итоге с использованием массивов:

$ set -- a abc xyz 
$ args=("[email protected]") 
$ for prefix in foo bar baz who why; do prefixed1+=("${args[@]/#/$prefix}"); done 
$ echo command "${prefixed1[@]}" 
command fooa fooabc fooxyz bara barabc barxyz baza bazabc bazxyz whoa whoabc whoxyz whya whyabc whyxyz 
$ 

или (отметив, что вы должны получить последовательность правильного):

$ for prefix in 123 456; do prefixed1+=("${args[@]/#/$prefix}"); done 
$ for prefix in foo bar; do prefixed2+=("${prefixed1[@]/#/$prefix}"); done 
$ echo command "${prefixed2[@]}" 
command foo123a foo123abc foo123xyz foo456a foo456abc foo456xyz bar123a bar123abc bar123xyz bar456a bar456abc bar456xyz 
$ 

Обратите внимание, что это сохраняет пробелы в аргументах :

$ unset prefixed1 prefixed2 
$ set -- 'a b' 'x y z' 
$ args=("[email protected]") 
$ for prefix in 'p p-' '123 456 '; do prefixed1+=("${args[@]/#/$prefix}"); done 
$ echo command "${prefixed1[@]}" 
command p p-a b p p-x y z 123 456 a b 123 456 x y z 
$ for prefix in 'foo 1-' 'bar 2-'; do prefixed2+=("${prefixed1[@]/#/$prefix}"); done 
$ echo command "${prefixed2[@]}" 
command foo 1-p p-a b foo 1-p p-x y z foo 1-123 456 a b foo 1-123 456 x y z bar 2-p p-a b bar 2-p p-x y z bar 2-123 456 a b bar 2-123 456 x y z 
$ printf "[%s]\n" "${prefixed2[@]}" 
[foo 1-p p-a b] 
[foo 1-p p-x y z] 
[foo 1-123 456 a b] 
[foo 1-123 456 x y z] 
[bar 2-p p-a b] 
[bar 2-p p-x y z] 
[bar 2-123 456 a b] 
[bar 2-123 456 x y z] 
$ 

И первый цикл может быть:

for prefix in 'p p-' '123 456 '; do prefixed1+=("${@/#/$prefix}"); done 

без использования массива ${args[@]}.

+0

Nice! .......... – hek2mgl

+0

Спасибо! Есть ли способ масштабировать это для больших '{foo, bar, baz, ...} $ @' или '{foo, bar} {123,456} $ @'? – arcyqwerty

Смежные вопросы