awk

awk

我有一个txt像这样的文件:

Large 0
Large 0 
Large 1
Large 2
Medium 0
Medium 1
Medium 1    
small 1
small 3

我想组合所有不同的大、中、小线,这样它就会输出如下内容:

Large 3
Medium 2
Small 4

我有另一个类似的问题,但另一个文件只是单词,例如:

MVCC Cybersecurity
MVCC Cybersecurity
MVCC Cybersecurity

我希望它输出学位的总和,即网络安全的总次数。

MVCC 3

答案1

perl -lane '@F == 2 and $h{$F[0]}+=$F[1]}{print "$_ $h{$_}" for keys %h' yourfile

读起来是:当您的行恰好有 2 个字段时,则更新哈希值,其中键的第二个字段是第一个键。最后,只需打印键和相应的值即可。

哈希 %h 的数据结构是:

%h = ( ... LARGE => running_sum, ... );

awk

awk '
   NF == 2 { seen[$1] += $2 }
   END{
      for(i in seen)
         print i, seen[i]
   }
' yourfile

答案2

看看gnu数据混合

$ datamash -W -g 1 sum 2 < ex.txt
Large   3
Medium  2
small   4
  • -W由空格分隔的列(默认是制表符)
  • -g 1按第 1 列分组
  • sum 2 求和列2

第二个例子不是很清楚;下面只是统计出现的次数...

$ datamash -W -g 1 count 2 < ex2.txt
MVCC 3

答案3

使用Python的groupby()

python的 ( itertools)干得不错通过...分组()。下面是针对您的两个(部分)问题的两个小脚本。

只需将代码复制到一个空文件中,设置文本文件的路径并通过以下命令运行它:

python3 /path/to/script.py

你问题的第一部分;获取总计

#!/usr/bin/env python3
from itertools import groupby
from operator import itemgetter
f = '/path/to/file'
for i, n in groupby([l.split() for l in open(f)], itemgetter(0)):
    print(i, sum([int(n[1]) for n in list(n)]))

其中f是文件的路径,用引号引起来

输出:

Large 3
Medium 2
small 4

问题的第二部分,计算具有相似第一列的行数

是对第一个的简单编辑:

#!/usr/bin/env python3
from itertools import groupby
from operator import itemgetter
f = '/path/to/file'
for i, n in groupby([l.split() for l in open(f)], itemgetter(0)):
    print(i, len(list(n)))

其中 f(再次)是文件的路径,用引号引起来。

在一个文件上:

MVCC Cybersecurity
MVCC Cybersecurity
MVCC Cybersecurity
Monkey Cybersecurity
Monkey Cybersecurity

它给出输出:

MVCC 3
Monkey 2

笔记

在您的示例中,行已排序。因此我认为我们不需要先对行进行排序。如果您的线路未排序,请注明。

解释

[l.split() for l in open(f)]

打开文件f,读取其行并将其拆分。

groupby([l.split() for l in open(f)], itemgetter(0))

随后团体第一项的行,以及

sum([int(n[1]) for n in list(n)])

对分组行中的数字总数进行求和。

相关内容