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脚本.
好吧,如果我没读错的话,你会得到:
文件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 作为排序键,这会极大地简化事情。这会降低缓存大小,因为您会知道是否已经看到匹配的值以及何时转储早期缓存的数据。