对文件中的列运行(垂直?)差异

对文件中的列运行(垂直?)差异

我们公司从第三方获取库存文件。这些文件采用固定格式,包含 13 位 EAN(类似 UPC 代码)以及其他数据。我们的数据库中还有 EAN 主列表。

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

例如:主
1234567890123
4567890123456

新文件 1234567890123 4567890123456
5678901234567 <- 删除此文件

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

我目前在 PHP 中执行此操作。问题是两个文件各有大约 400 万行,而我的脚本占用了大量内存。我目前将整个主列表加载到 RAM 中并执行 isset()。

是否有任何智能的 Linux 技巧/程序可以帮助我?

答案1

用更适合 grep 的方式重新表述这个问题,您想要打印与某个 EAN 主列表中的 EAN 匹配的所有行。

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

  • 从中提取所有 EANmaster
  • 将 EAN 列表压缩到正则表达式中
  • 将正则表达式输入到 egrep

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

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

应该接近(awk如果master仅仅是一个 EAN 列表,你可以删除它;最后使用令人讨厌的 sed 来删除|管道其余部分导致的尾随)

如果 EAN(或类似 EAN 的 13 位数字模式)出现在数据的其他位置,则上述内容会失效,并且需要更复杂的正则表达式来将搜索限制在特定列。

答案2

尝试这样的操作:

# 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}'

相关内容