shell 中的自然语言循环

shell 中的自然语言循环

有没有一种自然的方式可以在不明确使用循环构造的情况下对一组输入循环运行命令?我的意思是以一种类似于我们用英语说话的方式。

例如,

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吗?还有其他 shell 具有类似的功能吗?

它不必与我在此处放置的语法完全相同,但必须是一些惯用语法,并且不像嵌套循环那样笨重。

答案1

您可以将for循环隐藏在 shell 函数中。以下是基于问题中的示例的相当脆弱的实现:

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
$ _

答案2

我仍在寻找更好的答案,但这里有一个临时的“解决方案”。

在了解了 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\;

还是有点尴尬。不确定其他 shell 是否有更好的选择。

相关内容