合并2个非常大的文本文件,更新每一行,而不使用内存

Bru*_*ial 6 php python memory merge file-io

假设我有两个文本文件,每个文件大约有200万行(每个文件大小约为50-80MB).两个文件的结构是相同的:

Column1 Column2 Column3
...
Run Code Online (Sandbox Code Playgroud)

第1列永远不会更改,第2列:两个文件中的相同值可能不同,并且两个文件的顺序不同,Column3是一个数字,并且在每个文件中都不同.

我需要能够将它们合并到一个文件中,与第2列匹配.如果两个文件中都存在Column2,则通过将两个文件中的Column3值一起添加来更新Column3.

如果文件不是那么庞大,我可以通过将两个文件的每一行读入数组并从那里开始,轻松地在PHP中执行此操作,但这样做很容易使可用内存过载.

有没有办法在不将每一行加载到内存中的情况下执行此操作?我对PHP很熟悉,但如果它们不是太复杂而无法理解,则可以使用Python,Java或Shell脚本.

Mar*_*c B 1

好吧,如果我没读错的话,你会得到:

文件1:

abc 12 34
abc 56 78
abc 90 12
Run Code Online (Sandbox Code Playgroud)

文件2:

abc 90 87  <-- common column 2
abc 12 67  <---common column 2
abc 23 1   <-- unique column 2
Run Code Online (Sandbox Code Playgroud)

输出应该是:

abc 12 101
abc 90 99
Run Code Online (Sandbox Code Playgroud)

如果是这种情况,那么就像这样(假设它们是 .csv 格式):

$f1 = fopen('file1.txt', 'rb');
$f2 = fopen('file2.txt', 'rb');
$fout = fopen('outputxt.');

$data = array();
while(1) {
    if (feof($line1) || feof($line2)) {
        break; // quit if we hit the end of either file
    }

    $line1 = fgetcsv($f1);
    if (isset($data[$line1[1]])) {
       // saw the col2 value earlier, so do the math for the output file:
       $col3 = $line1[2] + $data[$line1[1]];
       $output = array($line[0], $line1[1], $col3);
       fputcsv($fout, $output);
       unset($data[$line1[1]]);
    } else {
       $data[$line1[1]] = $line1; // cache the line, if the col2 value wasn't seen already
    }

    $line2 = fgetcsv($f2);
    if (isset($data[$line2[1]])) {
       $col3 = $data[$line2[1]] + $line2[2];
       $newdata = array($line2[0], $line2[1], $col3);
       fputcsv($fout, $newdata);
       unset($data[$line2[1]]); // remove line from cache
    } else {
       $data[$line2[1]] = $line2;
    }
}

fclose($f1);
fclose($f2);
fclose($fout);
Run Code Online (Sandbox Code Playgroud)

这超出了我的想象,没有经过测试,可能行不通,YMMV,等等......

如果您对两个输入文件进行预排序,那么将使用 column2 作为排序键,这会极大地简化事情。这会降低缓存大小,因为您会知道是否已经看到匹配的值以及何时转储早期缓存的数据。