In Bash, how to convert number list into ranges of numbers?

后端 未结 2 753
没有蜡笔的小新
没有蜡笔的小新 2021-01-05 07:08

Currently I have a sorted output of numbers from a command:

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

I would like to condense these number lists

相关标签:
2条回答
  • 2021-01-05 07:34

    Only with a function in bash:

    #!/bin/bash
    
    list2range() {
      set -- ${@//,/ }       # convert string to parameters
    
      local first a b string IFS
      local -a array
      local endofrange=0
    
      while [[ $# -ge 1 ]]; do  
        a=$1; shift; b=$1
    
        if [[ $a+1 -eq $b ]]; then
          if [[ $endofrange -eq 0 ]]; then
            first=$a
            endofrange=1
          fi
        else
          if [[ $endofrange -eq 1 ]]; then
            array+=($first-$a)
          else
            array+=($a)
          fi
          endofrange=0
        fi
      done
    
      IFS=","; echo "${array[*]}"
    }
    
    list2range 18,19,62,161,162,163,165
    

    Output:

    18-19,62,161-163,165
    
    0 讨论(0)
  • 2021-01-05 07:59

    Yes, shell does variable substitution, if prev is not set, that line becomes:

    if [ -ne $n+1] 
    

    Here is a working version:

    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
    
    0 讨论(0)
提交回复
热议问题