我如何获得像“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,“ - ”和“,”
答案 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