在文件中的列上运行(vertical?)diff

在我们公司,我们从第三方提取库存文件。 这些文件是固定的格式,包含13位EAN(想想UPC代码)以及其他数据。 我在我们的数据库中也有EAN的主要列表。

我想将主文件与新文件进行比较,并从新文件中删除所有包含EAN的行,这不在主文件中。

例如:主人
1234567890123
4567890123456

新文件1234567890123 4567890123456
5678901234567 < – 删除这一个

新文件包含EAN以外的数据。 EAN在第一列。 数据以制表符分隔。

我目前正在做这个在PHP中。 问题是这两个文件有大约4百万。 每个行,我的脚本消耗大量的内存。 我目前加载整个主列表到RAM和做isset()s。

有什么聪明的Linux技巧/程序可以帮助我吗?

以更友好的方式改写问题,您希望从EAN的主列表中打印出与EAN匹配的所有行。

假设类似于EAN的东西不会出现在EAN列以外的任何地方,请尝试:

  • master提取所有EAN
  • 把那个EAN列表弄成一个正则expression式
  • 喂正则expression式egrep

假设EAN是master的第一列(并且该主站包含其他列)

 egrep "(`cat master | awk '{print $1}' | tr '\n' '\\|' | sed 's/|$//'`)" newfile 

应该接近(如果master只是一个EAN列表,你可以删除awk ;讨厌的sed在结尾删除从pipe道的其余部分产生的尾部)

如果EAN(或类似EAN的13位数字模式)存在于数据中的其他地方并且需要更复杂的正则expression式来将search限制到特定的列,则上述内容将被打破。

尝试这样的事情:

 # Put each code in one line, and sort them sed -e 's/\ /\n/g' new | sort > neweans sed -e '/s\ /\n/g' master | sort > mastereans # Diff them by columns, and delete from the list # the new's that are not in master. Then, print them diff -y neweans mastereans | grep -v "<" | awk '{print $1}'