使用 php 根据第一列合并 2 个文本文件
Merge 2 text files based on first column using php
我有 2 个包含多行的日志文件,例如
第一个:
1|2016-04-13|...
3|2016-03-13|...
第二个:
2|POST|accept: txt|...
3|POST|accept: txt|...
预期结果:
3|2016-03-13|...|POST|accept: txt|...
所以我需要使用 PHP 脚本根据第一列 (ID) 将所有数据合并到一个文件中。
注意:行数可以不同。只需要交集(顺序敏感)
打开两个日志文件。
您可以使用 fopen 和 fgets(在 foreach/while 循环中)将行放入数组
或使用 file_get_contents 将文件分解为 \n(\r\n 在 Win 上)
现在您应该有两个包含两个日志文件行的数组。
然后你这样做:
$log1Lines = array("3|...|...", "4|...|...");
$log2Lines = array("2|...|...", "3|...|...");
$merged = array();
foreach($log1Lines as $row1){
$id1 = explode("|", $row1)[0];
foreach($log2Lines as $row2){
$exploded = explode("|", $row2);
$id2 = array_shift($exploded);
if($id1 == $id2){
$merged[$id1] = $row1 . "|" . implode("|", $exploded);
}
}
}
print_r($merged);
理论上它应该可以在没有循环的情况下实现(通过 array_intersect 比较两个数组之间的解析索引),但我现在没有解决方案。
希望对您有所帮助。
我最近需要写一些非常相似的东西,所以我已经根据您的格式对其进行了一些更新。如有必要,这将支持 2 个以上的文件,并允许更改分隔符。
<?php
class Merger
{
protected $separator = '|';
protected $data = [];
protected $initialised = false;
public function mergeFile($filename)
{
$file = new SplFileObject($filename);
$fileKeys = [];
// Read the information out of the current file
while (!$file->eof()) {
$line = $file->fgets();
$parts = explode($this->separator, trim($line));
$id = array_shift($parts);
$fileKeys[] = $id;
$fileData[$id] = $parts;
}
// First pass: add everything
if (!$this->initialised)
{
$this->data = $fileData;
}
// Subsequent passes, only add things that have already been seen, then
// clear out anything that wasn't in the current file
else
{
foreach ($fileData as $id => $data)
{
if ($this->data[$id])
{
$this->data[$id] = array_merge($this->data[$id], $data);
}
}
$this->data = array_filter($this->data, function ($e) use ($fileKeys) {
return in_array($e, $fileKeys);
}, ARRAY_FILTER_USE_KEY);
}
$this->initialised = true;
}
public function output($filename)
{
foreach ($this->data as $id => $data)
{
$output .= $id . $this->separator . implode($this->separator, $data) . PHP_EOL;
}
file_put_contents($filename, $output);
}
}
$merger = new Merger;
$merger->mergeFile('1.txt');
$merger->mergeFile('2.txt');
echo $merger->output('output.txt');
我的解决方案是:
<?php
exec ("awk -F'|' -vOFS='|' '(NR==FNR){a[]=[=10=]; next}{if(a[]){print ,a[]}}' first.log second.log > result.log");
?>
我使用了execphp函数来执行shell脚本
awk -F'|' -vOFS='|' '(NR==FNR){a[]=[=11=]; next}{if(a[]){print ,a[]}}' first.log second.log > result.log
此处-F'|'
指定'|'符号作为分隔符,first.log
和 second.log
是我要合并的文件。
我有 2 个包含多行的日志文件,例如
第一个:
1|2016-04-13|...
3|2016-03-13|...
第二个:
2|POST|accept: txt|...
3|POST|accept: txt|...
预期结果:
3|2016-03-13|...|POST|accept: txt|...
所以我需要使用 PHP 脚本根据第一列 (ID) 将所有数据合并到一个文件中。
注意:行数可以不同。只需要交集(顺序敏感)
打开两个日志文件。
您可以使用 fopen 和 fgets(在 foreach/while 循环中)将行放入数组
或使用 file_get_contents 将文件分解为 \n(\r\n 在 Win 上)
现在您应该有两个包含两个日志文件行的数组。 然后你这样做:
$log1Lines = array("3|...|...", "4|...|...");
$log2Lines = array("2|...|...", "3|...|...");
$merged = array();
foreach($log1Lines as $row1){
$id1 = explode("|", $row1)[0];
foreach($log2Lines as $row2){
$exploded = explode("|", $row2);
$id2 = array_shift($exploded);
if($id1 == $id2){
$merged[$id1] = $row1 . "|" . implode("|", $exploded);
}
}
}
print_r($merged);
理论上它应该可以在没有循环的情况下实现(通过 array_intersect 比较两个数组之间的解析索引),但我现在没有解决方案。
希望对您有所帮助。
我最近需要写一些非常相似的东西,所以我已经根据您的格式对其进行了一些更新。如有必要,这将支持 2 个以上的文件,并允许更改分隔符。
<?php
class Merger
{
protected $separator = '|';
protected $data = [];
protected $initialised = false;
public function mergeFile($filename)
{
$file = new SplFileObject($filename);
$fileKeys = [];
// Read the information out of the current file
while (!$file->eof()) {
$line = $file->fgets();
$parts = explode($this->separator, trim($line));
$id = array_shift($parts);
$fileKeys[] = $id;
$fileData[$id] = $parts;
}
// First pass: add everything
if (!$this->initialised)
{
$this->data = $fileData;
}
// Subsequent passes, only add things that have already been seen, then
// clear out anything that wasn't in the current file
else
{
foreach ($fileData as $id => $data)
{
if ($this->data[$id])
{
$this->data[$id] = array_merge($this->data[$id], $data);
}
}
$this->data = array_filter($this->data, function ($e) use ($fileKeys) {
return in_array($e, $fileKeys);
}, ARRAY_FILTER_USE_KEY);
}
$this->initialised = true;
}
public function output($filename)
{
foreach ($this->data as $id => $data)
{
$output .= $id . $this->separator . implode($this->separator, $data) . PHP_EOL;
}
file_put_contents($filename, $output);
}
}
$merger = new Merger;
$merger->mergeFile('1.txt');
$merger->mergeFile('2.txt');
echo $merger->output('output.txt');
我的解决方案是:
<?php
exec ("awk -F'|' -vOFS='|' '(NR==FNR){a[]=[=10=]; next}{if(a[]){print ,a[]}}' first.log second.log > result.log");
?>
我使用了execphp函数来执行shell脚本
awk -F'|' -vOFS='|' '(NR==FNR){a[]=[=11=]; next}{if(a[]){print ,a[]}}' first.log second.log > result.log
此处-F'|'
指定'|'符号作为分隔符,first.log
和 second.log
是我要合并的文件。