破折号中的范围如何工作?

破折号中的范围如何工作?

我正在尝试找出如何在破折号中快速执行以下 bash 脚本。

for x in {1..5}
do
    for y in {a..c}
    do
    echo $HOME$x$y
    done
done

Dash 不支持大括号扩展,并且我不知道有任何其他方法可以获取类似范围的构造来模仿上面的脚本。我想我可以通过 while 循环来解决,但我不认为这是一个脚本改编,而是一个完全不同的野兽。

是否有可能在 Dash 中保留上述脚本的精神?是否可以在不使用 seq 等外部程序的情况下保留上述脚本的精神?如何?

答案1

括号扩展本身不是由 POSIX 定义的,您需要使用其他 POSIX 兼容工具中的选项进行转换。一种这样的方法是使用 ASCII 表来映射从字符的 ASCII 值到其字符值的转换printf()。查找man ascii值映射。

i=1
asciiStart=97
asciiEnd=99
while [ "$i" -le 5 ]
do
    while [ "$asciiStart" -le "$asciiEnd" ]
    do
        echo "$HOME$i$(printf "\\$(printf '%03o' "$asciiStart")")"
        asciiStart=$((asciiStart + 1))
    done
    asciiStart=97
    i=$(( i + 1 )) 
done

答案2

可能不会,因为如果有另一个功能可以完成大括号扩展的功能,则不需要大括号扩展......

请注意,如果您的列表不是静态的(例如上限不同),那么您也不能轻松地在 Bash 中使用大括号扩展,因为它{1..$n}不会执行您想要的操作(大括号扩展变量)。

另一方面,如果你的清单静态的,使用其他程序来创建列表并将它们直接插入到脚本中并不难,所以你最终会得到:

for x in 1 2 3 4 5; do
    for y in a b c; do
        echo "$HOME$x$y"
    done
done

在 shell 中使用 awhile生成字符列表似乎也有点困难。

所以,抱歉,但这似乎用其他语言更容易完成。像 Perl 一样:

highnum=5 highchar=c perl -le 'for $x (1..$ENV{highnum}) { 
                                  for $y ("a"..$ENV{highchar}) { 
                                     print "$ENV{HOME}/$x$y"; } }'

相关内容