我需要根据电子表格中的两列计算唯一值的数量。
假设文件如下所示,按姓名、姓氏、公司排序:
joe allen ibm
joe smith ibm
joe allen google
joe smith google
rachel allen google
我需要计算每个公司唯一名字的数量,同时忽略姓氏:
joe ibm 2
joe google 2
rachel google 1
我有这个代码:
sort file.tsv | uniq -ci | awk '{print $2,$1}'
如果我直接删除姓氏列,该代码就可以正常工作。但如果我不想删除该列,是否只需让 awk 忽略它,并将输出保存到新文件?
数据以制表符分隔\t
答案1
使用 GNU awk 解决方案二维数组:
gawk -F $'\t' '{a[$1][$3]++} END {for (i in a) for (j in a[i]) print i, j, a[i][j]}' foo.txt
a[$1][$3]++
对于每个名字和姓氏的组合,增加计数- 然后循环遍历名字以及与每个名字相关的公司名称。
另一种可以awk
使用旧形式的多维数组的方法是:
awk -F $'\t' '{a[$1, $3]++} END{for (i in a) {split (i, sep, SUBSEP); print sep[1], sep[2], a[i]}}' foo.txt
- 由于旧方法实际上使用了以 分隔的索引的连接
SUBSEP
,因此我们必须进行拆分SUBSEP
才能返回原始索引。
答案2
这是一个使用模块Counter
类的Pythonic 解决方案collections
,它将计算可迭代对象中每个元素出现的次数:
#!/usr/bin/env python2
import collections
with open('file.txt') as f:
names = []
for line in f:
names.append(line.strip().split()[0] + ' ' + line.strip().split()[2])
result_dict = collections.Counter(names)
for person in result_dict:
print person + ' ' + str(result_dict[person])
答案3
您可以利用cut
来选择要首先操作的列。因此,假设您的列由空格分隔,并且是 FNAME SNAME COMPANY,而我们只对第 1 列和第 3 列感兴趣,我们可以使用:
cut -d' ' -f1,3 file.tsv | sort | uniq -ci
这告诉cut
使用单个空格“ ”作为分隔符进行分隔,并将第 1 列和第 3 列传递到排序。
它将产生一些类似于以下内容的输出:
cut -d' ' -f1,3 file.tsv | sort | uniq -ci
2 joe google
2 joe ibm
1 rachel google
答案4
以下 perl 单行程序将为您提取数据:
perl -e '/(.*)\t.*\t(.*)/ and $a{"$1 $2"}++ for (<>); print "$_ $a{$_}\n" foreach (keys%a);' file.tsv
输出:
joe ibm 2
joe google 2
rachel google 1