我有一个字符串,其中包含多个出现的数字范围,用逗号分隔,例如
2-12,59-89,90-102,103-492,593-3990,3991-4930
现在我想删除所有直接相邻的范围并将其从字符串中删除,即删除-(x),(x+1)
形式的任何内容,以获得类似的内容:
2-12,59-492,593-4930
有人能想到一种方法来实现这个目标吗?老实说,我不会发布任何我尝试过的东西,因为我的所有尝试都非常不成功。对我来说,似乎不可能使用sed实际找到-(x),(x+1)
形式的任何内容,因为这需要对另一个数字进行操作或比较找到的数字,该数字必须是当前命令的一部分寻找数字。
如果每个人都同意sed不是这样做的正确工具,我会采取另一种方式,但我仍然感兴趣,如果可能的话。
答案 0 :(得分:4)
awk
awk -F, -v RS="-" -v ORS="-" '$2!=$1+1' file
使用适当的分隔符设置,在第二个字段不是+1时打印记录。
RS
是记录分隔符,ORS
是分页记录分隔符。
试验:
> awk -F, -v RS="-" -v ORS="-"
'$2!=$1+1' <<< "2-12,59-89,90-102,103-492,593-3990,3991-4930"
2-12,59-492,593-4930
答案 1 :(得分:2)
awk 解决方案:
awk -F'-' '{ r=$1;
for (i=2; i<=NF; i++) {
split($i, a, ",");
r=sprintf("%s%s", r, a[2]-a[1]==1? "" : FS $i)
}
print r
}' file
-F'-'
- 将-
(连字符)视为字段分隔符r
- 结果字符串split($i, a, ",")
- 通过分隔符a
,
a[2]-a[1]==1
- 关键条件,反映(x),(x+1)
输出:
2-12,59-492,593-4930
答案 2 :(得分:1)
这可能适合你(GNU sed):
sed -r ' s/^/\n/;:a;ta;s/\n([^-]*-)([0-9]*)(.*,)/\1\n\2\n\2\n\3/;Td;:b;s/(\n.*\n.*)9(_*\n)/\1_\2/;tb;s/(\n.*\n)(_*\n)/\10\2/;s/$/\n0123456789/;s/(\n.*\n[0-9]*)([0-8])(_*\n.*)\n.*\2(.).*/\1\4\3/;:z;tz;s/(\n.*\n[^_]*)_([^\n]*\n)/\10\2/;tz;:c;tc;s/([0-9]*-)\n(.*)\n(.*)\n,(\3)-/\n\1/;ta;s/\n(.*)\n.*\n,/\1,\n/;ta;:d;s/\n//g' file
这种概念验证sed解决方案,迭代地递增并将一个范围的结束与另一个范围的开始进行比较。如果比较为真,则删除两者并重复,否则它将移至下一个范围并重复,直到比较所有范围。