In Bash, how to convert number list into ranges of numbers?
arrays, bash, numbers, range
Solution
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
Problem
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 into a list of single numbers or ranges of numbers 18-19,62,161-163,165 I thought about trying to sort through the array in bash and read the next number to see if it is +1... I have a PHP function that does essentially the same thing, but I'm having trouble transposing it to 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); } } ``` I'm thinking there's probably a one-liner in bash that could do this but my Googling is coming up short.... UPDATE: Thank you @Karoly Horvath for a quick answer which I used to finish my project. I'd sure be interested in any simpler solutions out there.