【发布时间】:2017-06-26 15:35:05
【问题描述】:
假设一个文本文件file 包含多个离散数字范围,每行一个。每个范围前面都有一个字符串(即范围名称)。每个范围的下限和上限由破折号分隔。每个数字范围后跟一个分号。各个范围已排序(即范围 101-297 在 1299-1301 之前)并且不重叠。
$cat file
foo 101-297;
bar 1299-1301;
baz 1314-5266;
请注意,在上面的示例中,三个范围不构成从整数 1 开始的连续范围。
我相信 awk 是填补缺失数字范围的合适工具,这样所有范围合起来形成从 {1} 到 {最后一个范围的上限}的连续范围。如果是这样,您将使用什么 awk 命令/函数来执行任务?
$cat file | sought_awk_command
new1 1-100;
foo 101-297;
new2 298-1298;
bar 1299-1301;
new3 1302-1313;
baz 1314-5266;
--
编辑 1:经过仔细评估,下面建议的代码在另一个简单示例中失败。
$cat example2
foo 101-297;
bar 1299-1301;
baz 1302-1314; # Notice that ranges "bar" and "baz" are continuous to one another
qux 1399-5266;
$ awk -F'[ -]' '$3-Q>1{print "new"++o,Q+1"-"$3-1";";Q=$4} 1' example2
new1 1-100;
foo 101-297;
new2 298-1298;
bar 1299-1301;
baz 1302-1314;
new3 1302-1398; # ERROR HERE: Notice that range "new3" has a lower bound that is equal to upper bound of "bar", not of "baz".
qux 1399-5266;
--
编辑 2: 非常感谢 RavinderSingh13 帮助解决这个问题。但是,建议的代码仍会生成与给定目标不一致的输出。
$ cat example3
foo 35025-35144;
bar 35259-35375;
baz 35376-35624;
qux 37911-39434;
$ awk -F'[ -]' '$3-Q+0>=1{print "new"++o,Q+1"-"$3-1";";Q=$4} {Q=$4;print}' example3
new1 1-35024;
foo 35025-35144;
new2 35145-35258;
bar 35259-35375;
new3 35376-35375; # ERROR HERE: Notice that range "new3" has been added, even though ranges "bar" and "baz" are contiguous.
baz 35376-35624;
new4 35625-37910;
qux 37911-39434;
【问题讨论】:
-
您说“各个范围已排序(即,范围 101-297 在 1299-1301 之前)并且不重叠。”但随后发布了
example2,它们确实重叠(bar 1299-1301;和baz 1301-1314;在1301重叠)。它们是重叠还是不重叠?另外 - awk 不是 bash 工具,它是一个完全独立的工具,可用于所有标准 UNIX 安装和一些其他操作系统。 -
@EdMorton 范围不重叠。
example2包含错误。我的错。它应该是bar 1299-1301和baz 1302-1314。我已经相应地纠正了这个例子。关于bash作为一个 UNIX(而不是专门的 bash)工具也采取了这一点。 -
没问题,我发布的脚本可以正常工作。
-
数据的期望输出是什么:
1-100。102-200,即。当范围之间只有一个值时?
标签: bash awk integer range continuous