计算两个文件中的公共集的数量

时间:2014-01-15 08:13:37

标签: python awk match

我想帮助您编写一个脚本来计算两个文件中常用数字的数量。我的文件格式如下所示,

文件1

0: 152 145 148
1: 251 280 428
2: 42 281 407
3: 289 292 331
4: 309 212 226
5: 339 336 376
6: 339 376 380
7: 41 406 205
8: 237 418 193

文件2

0: 251 280 428
1: 309 212 226
2: 339 336 376
3: 339 376 380
4: 420 414 199
5: 418 193 237
6: 203 195 200
7: 287 161 257
8: 287 257 158
9: 263 369 15
10: 285 323 327

第一列只是序列号,在检查两个文件之间的匹配时应该被忽略,并且具有不同排序的相同数字的集合应该被视为常见的(for e.g 237 418 193 = 418 193 237)

在这种情况下,预期结果将是......

5 # no. of common sets
251 280 428
309 212 226
339 336 376
339 376 380
237 418 193

我尝试过使用awk脚本 -

awk 'FNR==NR{a[$3]=$0;next}{if(b=a[$3]){print b}}' file1 file2

不幸的是,设置“237 418 193”没有计算,因为它在第二个文件中有不同的排序(418 193 237)。

使用awkPython脚本可以帮助我完成此任务。

感谢任何帮助?

5 个答案:

答案 0 :(得分:1)

解析文件,创建set行,每个元素按字典顺序排序。

file1_sets = {tuple(sorted(line.split()[1:])) for line in open(file1, 'r')}
file2_sets = {tuple(sorted(line.split()[1:])) for line in open(file2, 'r')}

然后看看另一个

中存在多少个
count = sum([f in file2_sets for f in file1_sets])

(根据评论编辑)

答案 1 :(得分:0)

试试这个python代码:

data1, data2 = [], []
for fname, data in [('file1.txt', data1), ('file2.txt', data2)]:
    for line in open(fname):
        data.append(set(line.strip().split()[1:]))

common = [s for s in data1 if s in data2]
for c in common:
    print c
print len(common)

输出:

set(['280', '251', '428'])
set(['309', '212', '226'])
set(['336', '339', '376'])
set(['380', '339', '376'])
set(['237', '418', '193'])
5

答案 2 :(得分:0)

使用集合和.intersection

with open("21132195_1.txt") as fh1, open("21132195_2.txt") as fh2:
    number_sets1 = set(frozenset(line.split()[1:]) for line in fh1)
    number_sets2 = set(frozenset(line.split()[1:]) for line in fh2)

common_number_sets = number_sets1.intersection(number_sets2)

print "%i # no. of common sets" % len(common_number_sets)
print "\n".join([" ".join(s) for s in common_number_sets])

将作为输出:

5 # no. of common sets
339 376 380
251 280 428
212 226 309
193 237 418
336 339 376

答案 3 :(得分:0)

在Gnu Awk 4.1版中,您可以使用PROCINFO["sorted_in"]之类的:

gawk -f  c.awk file1 file2

其中c.awk是:

BEGIN {PROCINFO["sorted_in"]="@val_num_asc"}
NR==FNR {
    b[getRow()]++
    next
}
{
    c=getRow()
    if (c in b)
        a[++j]=c
}
END{
    print j" # no. of common sets"
    for (i in a) 
        print a[i]
}

function getRow(b,d,i) {
    for (i=2; i<=NF; i++)
        d[i]=$i
    for (i in d)
        b=(b=="")?d[i]:(b" "d[i])
    return b
}

输出:

5 # no. of common sets
193 237 418
212 226 309
251 280 428
336 339 376
339 376 380

答案 4 :(得分:0)

使用shell的另一种方式。

cat file1 file2 |while read x line  
do 
   arr2=($(for val in $line;do echo "$val";done|sort -n))
   echo "${arr2[@]}"
done|awk '++a[$1,$2,$3]>1'

251 280 428
212 226 309
336 339 376
339 376 380
193 237 418