我有两个文件urls.log
(1Gb)和ids.txt
(20M),第一个文件urls.log
如下所示:
/product/80x80/436284940/
/product/100x100/1051907917/Pavillon-2.jpg
/product/140x140/988563549/LITTLE-ROSE-Mikrofasermischung-Maxi-Slips-uni-5er-Pack.jpg
/product/100x100/504170379/Dunlop-SP-Sport-Maxx-215-40R17-87V-XL-VW1-MFS.jpg
...
第二个文件ids.txt
如下所示:
988563549
988563540
988563541
...
结果应为:(result.txt
)
/product/140x140/988563549/LITTLE-ROSE-Mikrofasermischung-Maxi-Slips-uni-5er-Pack.jpg
由于988563549
中存在ids.txt
,因此我们需要urls.log
中的此记录,否则,我们不需要该行,我们也不需要/product/80x80/5252352/
因为它的文件夹不是图像。
我在PHP中写的是:
$file = '/combined/combine.url.sanitized.access_log';
$handle = fopen($file, "r");
if ($handle) {
while (($line = fgets($handle)) !== false)
{
$handleids = fopen('/script/ids.txt', "r");
while (($lineIds = fgets($handleids)) !== false)
{
if (strpos($line, trim($lineIds)) !== false)
{
file_put_contents('result.txt', $line . PHP_EOL, FILE_APPEND | LOCK_EX);
break;
}
}
fclose($handleids);
file_put_contents('result.txt', '=' . PHP_EOL, FILE_APPEND | LOCK_EX);
}
fclose($handle);
}
这项工作如此缓慢,我计算了时间,大约需要60天。那我该怎样改进呢?可以用其他语言来实现,但我对其他语言并不熟悉,所以请告诉我更多细节。
答案 0 :(得分:2)
当您拥有一个充满模式的文件和另一个搜索这些模式的文件时,您可以使用-f
的{{1}}选项(grep
仅用作您的模式文件包含固定字符串,而不是正则表达式模式):
-F
要忽略任何以斜杠结尾的内容,您可以再次使用grep -Ff ids.txt urls.log
管道grep
来排除模式:
-v
这应该比PHP脚本更快。如果它仍然太慢,您可能需要考虑使用Perl(例如this question)或Python。
答案 1 :(得分:0)
首先,你可以将ids.txt缓存到一个集合中。 然后,启动一个reactor线程来将urls.log的每一行迭代到队列中, 并启动一些工作线程来使用此队列,在每个工作线程中,使用ids.txt生成的集合来过滤urls.log中的每一行。