将数据聚类在文件中

时间:2014-11-22 19:29:38

标签: python bash awk sed grep

我有以下格式的文件

--
752721  1
757734  1
757936  1
758144  1
758324  1
--
842825  1
843940  1
--
1301199 1
--
--
1302408 1
1302555 1
--
--
--
--
1306558 1
1307638 1
1308628 1

' - '是一个分隔符。我想像这样将这些条目聚集在一起:

752721 - 758324 5
842825 - 843940 2
1301199 1
1302408 - 1302555 2
1306558 - 1308628 3

显示群集的范围,并在其旁边附加其中元素数量的计数。

我在awk和sed中尝试了几个选项。不知怎的,他们没有成功。欢迎任何其他建议。

3 个答案:

答案 0 :(得分:3)

$ awk 'function out(){if (count>0)printf "%s - %s %s\n",first,last,count;count=0}; /--/{out()} NF<2 {next} count==0{first=$1} {last=$1;count+=1} END{out()}' file2
752721 - 758324 5
842825 - 843940 2
1301199 - 1301199 1
1302408 - 1302555 2
1306558 - 1308628 3

如何运作

此代码使用三个变量。 firstlast表示范围,count是在该范围内找到的行数。

  • function out(){if (count>0)printf "%s - %s %s\n",first,last,count;count=0}

    这定义了一个函数out,如果有要打印的集群,即count>0,则打印集群。

  • /--/{out()}

    每当我们到达分隔符时,请调用函数out以打印出任何群集数据。

  • NF<2 {next}

    如果这是空行或分隔符行,请跳过其余命令并跳转到下一行

  • count==0{first=$1}

    如果这是群集的第一行,请设置first

  • {last=$1;count+=1}

    更新lastcount

  • END{out()}

    在文件末尾,打印最后一个群集的数据。

细化

此版本更贴近所需的输出。当firstlast相同时,它不会打印“第一个 - 最后一个”:

$ awk 'function out(){if (count>0){printf "%s ",first; if(first!=last)printf"- %s ",last; print count;count=0}}; /--/{out()} NF<2 {next} count==0{first=$1} {last=$1;count+=1} END{out()}' file
752721 - 758324 5
842825 - 843940 2
1301199 1
1302408 - 1302555 2
1306558 - 1308628 3

这是通过将out函数中的逻辑更改为:

来实现的
function out(){
    if (count>0){
        printf "%s ",first
        if(first!=last)
            printf"- %s ",last; 
        print count;count=0;
    }
}

答案 1 :(得分:2)

with open('/path/to/output') as infile:
    buffer = []
    for line in infile:
        line = line.split()[0]
        if line == '--':
            if buffer:
                print("{} - {} {}".format(buffer[0], buffer[-1], len(buffer)))
                buffer = []
        else:
            buffer.append(int(line))
    if buffer:
        print("{} - {} {}".format(buffer[0], buffer[-1], len(buffer)))

输出:

752721 - 758324 5
842825 - 843940 2
1301199 - 1301199 1
1302408 - 1302555 2
1306558 - 1308628 3

答案 2 :(得分:1)

从stdin读取的代码(或作为第一个命令行参数传递的文件名):

import fileinput

def report(first,last,count):
  if first == last:
    print first, count
  else:
    print first, "-", last, count

first = None
last = None
count = 0
for line in fileinput.input():
  line = line.strip()
  if line == "--":
    if last:
      report(first, last, count)
    last = first = None
    count = 0
  else:
    words = line.split()
    i = words[0]
    n = int(words[1])
    if not first:
      first = i
      count = 0
    last = i
    count = count + n
if first:
  report(first, last, count)