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

Например,

some-command -a john,jane -b doe,roe

вместо

for a in john jane; do
   for b in doe roe; do
     some-command -a $a -b $b
   done
done

Вы можете сделать это в bash? Есть ли другая оболочка, которая имеет такую функцию?

Это не должен быть тот же самый синтаксис, который я здесь привожу, но что-то идиоматическое, не такое громоздкое, как вложенный цикл.

2 ответа2

1

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

loop ()
{
    for i in `echo $3 |tr ',' ' '`;
    do
        for j in `echo $5 |tr ',' ' '`;
        do
            $1 $2 $i $4 $j;
        done;
    done;
}

Тогда эта функция будет вызываться как loop some-command -a john,jane -b doe,roe . Например:

$ for i in /{bin,media}; do for j in /{srv,tmp/tmp}; do \ls -d $i $j; done; done
/bin  /srv
/bin  /tmp/tmp
/media  /srv
/media  /tmp/tmp
$ loop ls -d /bin,/media "" /srv,/tmp/tmp
/bin  /srv
/bin  /tmp/tmp
/media  /srv
/media  /tmp/tmp
$ _
0

Я все еще ищу лучший ответ, но вот временное "решение".

Узнав о расширении скобок в bash, я пришел к этому. К сожалению, вы должны экранировать все специальные символы в команде или использовать кавычки:

eval 'some-command -a '{john,jane}' -b '{doe,roe}';'
eval some-command\ -a\ {john,jane}\ -b\ {doe,roe}\;

Например,

eval 'kubectl --context='{context1,context2}' --namespace='{ns1,ns2}' get pod;'
eval kubectl\ --context={context1,context2}\ --namespace={ns1,ns2}\ get\ pod\;

Все еще несколько неловко. Не уверен, что другие снаряды имеют лучший вариант.

Всё ещё ищете ответ? Посмотрите другие вопросы с метками .