我想帮助您编写一个脚本来计算两个文件中常用数字的数量。我的文件格式如下所示,
文件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)。
使用awk
或Python
脚本可以帮助我完成此任务。
感谢任何帮助?
答案 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