我有一个逗号分隔的数字字符串,如下所示:
1,2,3,5,6,7,8,9,12,14
我正在寻找在bash
脚本中使用的命令,该命令可以将相邻的数字组合成范围/连字符条目,如下所示:
1-3,5-9,12,14
初始字符串保证按升序排序。
发布于 2020-01-16 18:11:25
最后,我使用了一个数组来携带已识别的范围,得到了以下BASH函数。输入字符串是函数的第一个参数,结果通过第二个参数传回:
function compact_range {
arr=()
start=""
for cpu in ${1//,/ }; do
# Start a new range definition if necessary
[ -z "$start" ] && start=$cpu && range=$cpu && last=$cpu && continue
prev=$(( $cpu - 1 ))
# If the current CPU is not adjacent to the last CPU, start a new range
[ "$prev" -ne "$last" ] && arr+=($range) && start=$cpu && range=$cpu && last=$cpu && continue
# Current CPU is adjacent to an existing range, expand the current range
range="${start}-${cpu}" && last=$cpu
done
# Append the last range to the array of ranges
arr+=($range)
# Return a comma delimited list of ranges
eval $2=$(IFS=,;printf "%s" "${arr[*]}")
}
谢谢大家的建议。
发布于 2020-01-16 00:06:39
使用perl:
perl -pe 's/\b(\d+)(?{$q=$1+1})(?:,(??{$q})\b(?{$p=$q++})){2,}/$1-$p/g'
这是通过(?{...})
和(??{...})
表达式使用嵌入perl代码的正则表达式;第一个表达式只是计算嵌入式代码,而第二个表达式使用它返回的值作为模式。有关完整的描述,请参见perlre(1)
。
如果你也想要两个数字的范围,用{2,}
量词替换为+
(例如。1,2,7
-> 1-2,7
)。
发布于 2020-01-15 22:51:53
下面是一个简短的awk
脚本,它遍历以逗号分隔的排序整数列表,并在此过程中填充两个数组a
和b
。
a
数组将包含每个单调递增整数范围的起始整数,而b
将包含相应的结束整数。代码中的变量n
保存已找到的范围的数量。
BEGIN {
OFS = FS = ","
}
{
n = 0
a[++n] = $1
for (i = 1; i < NF; ++i)
if ($i != $(i+1) - 1) {
b[n] = $i
a[++n] = $(i+1)
}
b[n] = $NF
$0 = ""
for (i = 1; i <= n; ++i)
if (a[i] == b[i])
$i = a[i]
else
$i = sprintf("%d-%d", a[i], b[i])
print
}
该输出是通过迭代n
找到的不同范围并构造一个记录来创建的,其中每个字段要么是单个整数(对于长度为1的范围),要么是表示范围的开始和结束的字符串。
对所提供的数据进行测试,从文件中读取数据:
$ awk -f script.awk file
1-3,5-9,12,14
显然,您可以从标准输入中输入一个字符串,如下所示:
$ awk -f script.awk <<<"1,2,3,5,9,10,11,12,13"
1-3,5,9-13
https://unix.stackexchange.com/questions/562335
复制相似问题