按连续编号将项目分组在一起

按连续编号将项目分组在一起

我有一系列如下所示的文件,我需要将它们分组为“连续组”,每行以数字开头,应该从上到下读取文件,如果下面的下一行是相同的数字或者比上面的行少 1,它们应该“分组”在一起,如果有多行在一起也应该是这种情况。

最后的目标是从各个“组”的文件中生成一个数字,其中与每个组最接近的数字相差不止一个。我已在下面的示例文件下方显示了所需的输出。

78' Corner, Bristol City. Conceded by Wes Hoolahan.
75' Corner, Bristol City. Conceded by Ahmed Hegazi.
60' Corner, Bristol City. Conceded by Ahmed Hegazi.
51' Corner, Bristol City. Conceded by Sam Johnstone.
20' Corner, West Bromwich Albion. Conceded by Niki Mäenpää.
19' Corner, West Bromwich Albion. Conceded by Adam Webster.
13' Corner, Bristol City. Conceded by Ahmed Hegazi.
7' Corner, Bristol City. Conceded by Sam Johnstone.
2' Corner, Bristol City. Conceded by Sam Johnstone.

总体目标是获得行中匹配项相距超过 1 的总数,因此该文件有 9 行,我可以从一个简单的wc -l.我希望能够运行脚本/命令行来获得许多独立的匹配项。

因此,在上面的示例中,“19 & 20”应该分组在一起,因此总计数将为 8 个“独立”行。 (如果一条线与任何其他数字至少相差 1,则该线被视为独立)。

例如,如果在上面的示例中存在以 21 开头的行,则输出仍将为 8,因为它将与“19 & 20”命中分组,也可能存在具有相同编号的行,例如“ 19 和 19 英寸。

我不确定如果不编写更复杂的脚本来考虑要求,这有多大可能,但我在我的时代见过一些令人印象深刻的 sed/awk 行,所以可能是其中之一的工作。

答案1

由于您的数据文件已经排序,您只需将每行的第一个值(第一行之后)与前一个值进行比较 - 确保它们经过数字转换。因此,如果(如评论中所示)您想要的只是计数,您可以这样做:

awk '
  BEGIN { if(getline == 1) {last = $1+0; c = 1}}
  last - $1 > 1 {c++} 
  {last = $1+0} 
  END {print c}
' file

答案2

使用 GNU awk 处理 ENDFILE:

$ cat tst.awk
FNR==1 { prev=$1; cnt=1; fname=FILENAME; next }
(prev - $1) > 1 { cnt++ }
{ prev = $1 }
ENDFILE { print fname, cnt }

$ awk -f tst.awk *
file1 8
file2 3
file3 24

对于任何 awk:

$ cat tst.awk
FNR==1 {
    if ( NR > 1 ) {
        print fname, cnt
    }
    prev = $1
    cnt = 1
    fname = FILENAME
    next
}
(prev - $1) > 1 { cnt++ }
{ prev = $1 }
END { print fname, cnt }

相关内容