以某列作为主键比对两个文件内容代码实现

有的时候,你可能需要比较两个文件的实质内容是否一样,或者某一个文件的内容是否均包含在另一个文件,你可以看看本代码。

前言

这两天老得比对各种文件,比对我手上的数据和你手上的数据是否一致,比对上传的数据和计算用的数据是否一致等。但是之前用的一些比对文件的方法又不能很好地满足我的需求,总得手动各种弄,就写了这个小脚本。

我一般用的比对方式有三种,notpad++ 的 Compare 插件,Excel 的 Vlookup 函数 + 排序 + IF, linux 的 diff 命令。但是问题在于第一种和第三种主要用在两个文件行的排序一致的情况,而且也得肉眼去看比对结果。第二种用 Excel 倒是灵活,就是得手动各种弄,偶尔一次可以,经常这样做就废时间了。

脚本逻辑

这个脚本要求两个文件的列数相同,并且列的顺序也一样。两个文件指定以某一列作为主键(数据库的概念,主键不可以出现重复)。

首先比较两个文件的主键,画个韦恩图如下,最左边的部分表示只在第一个文件的主键,也就是只在第一个文件中的行(如果存在,则写入文件 only_in_file1.txt ),最右边同理 。中间重叠的部分就是两个文件共同的主键。

1

然后查看两个文件共同的主键部分,比对同一个主键在两个文件的行的内容是否一致,如果不一致,则将这两行内容写入到 diff_rows.txt 。

如果只在文件1中的行只在文件2中的行共同主键但是行内容不同的行,这三个均不存在,那就说明这两个文件在内容上完全一致

使用软件

  • python 3.8 及以上版本

输入文件格式

文本格式

输出文件格式

如果两个文件存在不一致,那么可能出现这三个文件。

only_in_file1.txt : 只在第一个文件出现的行

only_in_file2.txt : 只在第二个文件出现的行

diff_rows.txt : 两个文件主键相同但是行内容不一致的内容。

前两个文件就不用说了,唯一注意的地方是这三个文件文件分隔符用的都是tab,可能和输入文件的分隔符不一样。

第三个文件举个例子,见下方,前两行为一个不一致的地方,第一行为主键YYLNWJ119077114在第一个文件中的内容,第二行则为主键YYLNWJ119077114在第二个文件中的内容,可以看到这两行在最后一列内容不一致,第一个文件为 9,第二个文件为 -999 。第三行为空行,作为分隔。第四行和第五行是第二个不一致的地方。

1
2
3
4
5
6
YYLNWJ119077114	F	7	YYCFJYA1872471220191013	243.76	9
YYLNWJ119077114 F 7 YYCFJYA1872471220191013 243.76 -999

YYLNWJ119083106 F 8 YYCFJYA1874850920191031 193.26 9
YYLNWJ119083106 F 8 YYCFJYA1874850920191031 193.26 -999

运行代码

代码文件见: compair_two_files.py

将两个需要比较的文件和本程序放在一个文件夹内,运行命令示范如下:

1
python compair_two_files.py --file1 in_sz_phe --file2 out_sz_phe

参数说明

--file1: 第一个输入文件名称,必选

--file2: 第二个输入文件名称,必选

--key-column: 主键所在的列,可选,默认为 1,即默认第一列为主键。如果数据中无法指定一列作为主键,现在可以指定多列内容作为主键,以逗号分隔。举个例子,假如比对文件为母猪的繁殖数据,此时由于一头母猪有多条数据,你不能将母猪ID作为主键,因为会重复;但是你可以通过母猪ID+胎次来保证一行数据的唯一性,如果母猪ID为第一列,胎次为第4列,则此时这个参数的值为 1,4 。

--file-separator: 文件中的分隔符,可选,默认为空白字符。

代码说明

输入参数,打印参数

检验参数

检验两个文件是否存在且非空,两个文件的列数是否相同,主键是否为数字且在列数的范围内。如果存在问题,报错退出

检查文件

第一个文件

对于每一行判断列数,判断整行内容是否重复,判断主键是否重复,将内容写入到 dict1 中。

第二个文件

正常检查同第一个文件,判断第二个文件的主键是否在第一个文件中,将共同主键的行内容写入到 dict2 ,将只在第二个文件的行内容写入到 only_in_file2_list 。

提取只在第一个文件中的主键的行

上面已经提取了只在第二个文件中的行的内容,这里就提取只在第一个文件的内容,写入 only_in_file1_list

比较共同主键的行

比较两个文件共同主键的行的内容是否一致

综合判断

结合上述内容,综合判断,如果完全一致则打印退出。如果存在不一致,将不一致的地方写入文件。

更新

2021年12月4号

  1. 之前数据每行内容拆分时,漏了使用指定的分隔符,改回来了

  2. --key-column 参数现在可以指定多列。

  • 版权声明: 本博客所有文章除特别声明外,著作权归作者所有。转载请注明出处!
  • Copyrights © 2019-2022 Vincere Zhou
  • 访问人数: | 浏览次数:

请我喝杯茶吧~

支付宝
微信