
[英]how to convert a string of number with trailing x's into a list of unsigned numbers
[英]In Bash, how to convert number list into ranges of numbers?
目前我有一个命令的数字排序输出:
18,19,62,161,162,163,165
我想将这些数字列表压缩为单个数字或数字范围的列表
18-19,62,161-163,165
我想尝试在 bash 中对数组进行排序并读取下一个数字以查看它是否为 +1...
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);
}
}
我在想 bash 中可能有一个单行代码可以做到这一点,但我的谷歌搜索不足......
更新:感谢@Karoly Horvath 的快速回答,我曾经用它来完成我的项目。 我肯定会对那里的任何更简单的解决方案感兴趣。
是的,shell 会进行变量替换,如果没有设置prev
,那一行变成:
if [ -ne $n+1]
这是一个工作版本:
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
仅在 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
输出:
18-19,62,161-163,165
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.