【发布时间】:2015-06-09 19:08:41
【问题描述】:
我有一个将数字分配给 md5sum 的文件,如下所示:
0 0000001732816557DE23435780915F75
1 00000035552C6F8B9E7D70F1E4E8D500
2 00000051D63FACEF571C09D98659DC55
3 0000006D7695939200D57D3FBC30D46C
4 0000006E501F5CBD4DB56CA48634A935
5 00000090B9750D99297911A0496B5134
6 000000B5AEA2C9EA7CC155F6EBCEF97F
7 00000100AD8A7F039E8F48425D9CB389
8 0000011ADE49679AEC057E07A53208C1
另一个文件每行包含三个 md5sum,如下所示:
00000035552C6F8B9E7D70F1E4E8D500 276EC96E149571F8A27F4417D7C6BC20 9CFEFED8FB9497BAA5CD519D7D2BB5D7
00000035552C6F8B9E7D70F1E4E8D500 44E48C092AADA3B171CE899FFC6943A8 1B757742E1BF2AA5DB6890E5E338F857
我想要的是用第一个文件的整数替换第二个文件中的第一个和第三个 md5sums。目前我正在尝试以下 awk 脚本:
awk '{OFS="\t"}FNR==NR{map[$2]=$1;next}
{print map[$1],$2,map[$3]}' mapping.txt relation.txt
问题是脚本需要超过 16g 的内存,尽管硬盘上的第一个文件只有 5.7g。
【问题讨论】:
-
除了拆分文件并分块执行之外,您在脚本中没有什么不同的方法可以减少该数字。如果这就是它所需要的,那么这就是它所需要的。对不起。顺便说一句,不相关 - 将
{OFS="\t"}更改为BEGIN{OFS="\t"} -
你没有说第二个文件有多大。如果它与 file1 的行数相同,那么我看不到您的 16G RAM 问题的解决方案。祝你好运。
-
为什么第二个文件的大小很重要?脚本只逐行打印替换。
-
您超出了 16GB 限制(估计值)多少?如果只是少量,则可能值得以更密集的格式存储 md5sum 或者使用子字符串...
-
从行长来看,应该有大约 1.4 亿条记录,这意味着 2.8 亿个短字符串——其中一半是 32 字节长,一半甚至更短。在 64 位系统(必须如此)上,仅字符串数据的指针就是 2GB,这不是唯一的元数据。如果你想一次性做到这一点,我认为你不能用脚本语言来做到这一点。用母语将其降低到(估计)6-7 GB 应该是可能的。你会接受使用通用库的 C++ 解决方案吗?
标签: awk out-of-memory associative-array