我有一个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)])
对分组行中的数字总数进行求和。