比较不同文件中的两列和打印匹配,如果列中的记录之间的差异小于或等于0.001

时间:2016-10-08 12:41:59

标签: python awk

我有两个文本文件,例如file1.txt包含类似

的内容
100.145 10.0728
100.298 10.04
100.212 10.0286

和file2.txt包含类似

的内容
100.223 8.92739
100.209 9.04269
100.084 9.08411

我想比较两个文件的第1列和第2列并打印匹配 如果file1.txt和file2.txt中两列的差异小于或等于0.001。

2 个答案:

答案 0 :(得分:1)

只需读取两个文件,按换行符拆分,用空格拆分这些行,然后循环遍历第一个文件行,并检查每行是否符合此条件的第二个文件行。

with open("file1.txt", "r") as f:
  f1_content = f.read()

with open("file2.txt", "r") as f:
  f2_content = f.read()

f1_lines = [line.split() for line in f1_content.split("\n")]
f2_lines = [line.split() for line in f2_content.split("\n")]

for i, line in enumerate(f1_lines):
  if abs(float(line[0]) - float(f2_lines[i][0])) <= 0.001 and abs(float(line[1]) - float(f2_lines[i][1])) <= 0.001:
    print("Match at line {0}".format(i))

@BrianCain提出的使用zip的解决方案:

with open("file1.txt", "r") as f:
  f1_content = f.read()

with open("file2.txt", "r") as f:
  f2_content = f.read()

f1_lines = [line.split() for line in f1_content.split("\n") if line != ""]
f2_lines = [line.split() for line in f2_content.split("\n") if line != ""]

for line in zip(f1_lines, f2_lines):
  if abs(float(line[0][0]) - float(line[1][0])) <= 0.001 and abs(float(line[0][1]) - float(f2_lines[1][1])) <= 0.001:
    print("Match at line {0}".format(line))
使用zip的解决方案

请求解释: 首先我们打开两个文件(使用with,因为这会在块之后关闭文件)并将内容保存到某些变量中。我们使用read()代替readlines(),因为后者在换行时不会移除\n。所以我通常只使用read()并按\n分割,因为这样做。

然后我们为每个文件创建一个元组列表。列表中的每个条目代表一行,每个元组(这些条目之一)每列包含一个条目。这是使用list comprehensions

完成的
f1_lines = [line.split() for line in f1_content.split("\n") if line != ""]

现在我们可以迭代这些线。 zip对此非常有用,因为它可以将两个长度相等的列表组合到一个列表中,其中包含同一索引处的列表条目的元组。例如:

zip([1, 2, 3], [4, 5, 6])

会产生

[(1, 4), (2, 5), 3, 6)]

有关详情,请点击此处:zip

现在我们有了一个列表,其中包含行的元组,每个文件都有一个条目。每个条目本身都包含两个列条目:

[(['100.145', '10.0728'], ['100.223', '8.92739']),
 (['100.298', '10.04'], ['100.2985', '10.04001']),
 (['100.212', '10.0286'], ['100.084', '9.08411']),
 (['100.212', '100.2125'], ['100.084', '100.0845'])]

如果我们迭代这个列表,我们可以通过行[0]中的第一个[x]访问文件,通过行0中的第二个[y]访问列(访问第一个文件的行)第二栏)。 现在我们简单地从每行中减去第一个文件第一列值的第二个文件第一列值,取绝对值(仅得到正浮点数)并检查它是否小于或等于0.001。对于第二列也是如此,如果两者都为真(或者如果你使用OR),那么我们打印我们的消息。

答案 1 :(得分:0)

我会使用paste来合并文件,然后让awk完成剩下的工作:

paste file1.txt file2.txt |
awk '
  function abs(v) {return v < 0 ? -v : v}
  abs($1-$3) <= lim && abs($2-$4) <= lim
' lim=0.001
an answer by Stéphane Chazelas

复制的

abs函数定义