Bash:范围列表,如a-b,C,k,m-n,x-y,z

时间:2013-01-17 12:13:33

标签: bash list range

我如何获得像“1-6,8,15-20,23,25-28,30”这样的范围列表参数进行解析/扩展(到“1 2 3 4 5 6 8 15 16 17” 18 19 20 23 25 26 27 28 30“)与bash?如果bash不起作用,可以考虑其他一些普遍可用的Linux shell。

用例:我有一个脚本需要用给定的ID做一些事情,并且能够(一次)能够一次性处理“各种”ID列表/范围。现在我的脚本只需要一个ID范围参数AB,所以如果我的ID列表不是单个的连续范围,我需要使用不同的范围参数多次运行脚本(例如“AB,XY”变为两次运行,首先是“AB”然后是“XY”)。

list参数的简短规范: - 列表是一个范围,或用逗号分隔的几个范围(其他分隔符也可以) - 范围是A-B(A小于B),或单个数字X(特殊情况A = B) - 这是数字/整数范围/列表,因此列表中可能的字符是0-9,“ - ”和“,”

3 个答案:

答案 0 :(得分:2)

suku@ubuntu-vm:~$ echo {1..6} 8 {15..20} 23 {25..28} 30
1 2 3 4 5 6 8 15 16 17 18 19 20 23 25 26 27 28 30

确保你在每个参数之间放置空格。

仅供参考:这称为使用范围进行大括号扩展。

我正在使用bash 4.2.37

suku@ubuntu-vm:~$ bash --version
GNU bash, version 4.2.37(1)-release (x86_64-pc-linux-gnu)
Copyright (C) 2011 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>

This is free software; you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.

有关Brace Expansion的更多信息,请点击me

修改

您也可以使用变量替换:

suku@ubuntu-vm:~$ A=1;F=6;H=8;eval echo {$A..$F} $H {15..20} 23 {25..28} 30
1 2 3 4 5 6 8 15 16 17 18 19 20 23 25 26 27 28 30

答案 1 :(得分:1)

一个简单的解决方案是使用seq。如果范围由空格分隔,则可以使用for循环

for range; do
    case "$range" in
    *-*) for id in $(seq $(echo $range | sed -e 's/-/ /')); do
             do_something $id
         done
         ;;
    *) do_something $range ;;
    esac
done

您可以将其称为

bash ranges.sh 1-6 8 15-20 23 25-28 30

答案 2 :(得分:0)

这是一个bash函数,它使用参数扩展,read命令和seq命令来解析和扩展您给出的格式的字符串。

parse_range () {
    for range in ${1//,/ }; do
        IFS=- read a b <<< "$range"
        b=${b:-$a}
        seq $a $b
    done
}

for i in $(parse_range 1-6,8,15-20,23,25-28,30); do
    echo $i
done