在Bash中,如何将数字列表转换为数字范围?

jjc*_*son 7 arrays bash numbers range

目前我有一个命令的数字排序输出:

18,19,62,161,162,163,165

我想将这些数字列表压缩成单个数字或数字范围的列表

18-19,62,161-163,165

我想过尝试在bash中对数组进行排序并读取下一个数字以查看它是否为+1 ...我有一个基本相同的PHP函数,但是我将它转换为Bash时遇到了麻烦:

foreach ($missing as $key => $tag) {
    $next = $missing[$key+1];
    if (!isset($first)) {
        $first = $tag;
    }
    if($next != $tag + 1) {
        if($first == $tag) {
            echo '<tr><td>'.$tag.'</td></tr>';
        } else {
            echo '<tr><td>'.$first.'-'.$tag.'</td></tr>';
        }
        unset($first);
    }
}
Run Code Online (Sandbox Code Playgroud)

我认为可能有一个bash单线程可以做到这一点,但我的谷歌搜索正在缩短....

更新: 谢谢@Karoly Horvath快速回答我用来完成我的项目.我肯定会对那里更简单的解决方案感兴趣.

Kar*_*ath 6

是的,shell执行变量替换,如果prev未设置,则该行变为:

if [ -ne $n+1] 
Run Code Online (Sandbox Code Playgroud)

这是一个工作版本:

numbers="18,19,62,161,162,163,165"

echo $numbers, | sed "s/,/\n/g" | while read num; do
    if [[ -z $first ]]; then
        first=$num; last=$num; continue;
    fi
    if [[ num -ne $((last + 1)) ]]; then
        if [[ first -eq last ]]; then echo $first; else echo $first-$last; fi
        first=$num; last=$num
    else
        : $((last++))
    fi
done | paste -sd ","

18-19,62,161-163,165
Run Code Online (Sandbox Code Playgroud)

  • 我可以为单字符翻译推荐`tr`而不是`sed`吗?`tr,'\n'`(就此而言,您可以使用参数扩展并跳过子shell.) (2认同)
  • 如何使用`IFS =,`而不是`sed`? (2认同)
  • @xiaoyi是的,或者只是将数字放在一个数组中,然后使用`for`. (2认同)