根据列值合并/粘贴csv文件

时间:2017-04-24 12:15:35

标签: php bash csv unix centos

我没有在php或linux上找到任何具体的例子来执行此操作:

第一个csv文件

field1;field2;field3;...
   one;   two; three;...

第二个csv文件

field4;field3;field7;...
 some;  three;     ok;
 some;   four;  notok;

如您所见,他们共有 field3

所以,其中 field3.1st csv = field3.2nd csv 例如。三个=三个,

我需要最后的csv:

field1;field2;field3;field4;field3;field7 
   one;   two; three;  some; three;   ok;
   ...
   ...
   ... 

我试图用php

做到这一点
$lines = file($csvone);
$lined = file($csvtwo);
$listf = "/home/myuser/public_html/folder/finallist.csv";
$fh = fopen($listf, 'wa+') or die("can't open file");
foreach ($lines as $line_num => $line) {
  $arr = explode(";",$line);
  $ref = $arr[2];
  $ref = rtrim($ref);
  echo "$ref \n";
  foreach ($lined as $fine_num => $fine) { 
        $brr = explode(";",$fine);
        $refe = $brr[1];
        $refe = rtrim($refe);
        echo "$refe \n";
        if ($ref == $refe) {
            echo "$ref equal to $refe ! \n";
         $stringData = "$arr[0];$arr[1];$arr[2];$arr[3];$arr[4];$arr[5];$arr[6];$arr[7];$arr[8];$arr[9];$arr[10];$arr[11];$brr[0];$brr[1];$brr[2];$brr[3];$brr[4];$brr[5];$brr[6];$brr[7];$brr[8];$brr[9];$brr[10];$brr[11];$brr[12];$brr[13]";  
        $stringData = str_replace(array("\r","\n"),"",$stringData);
        $stringData .= PHP_EOL;
        fwrite($fh, $stringData); 
        }

    } 
}  
 fclose($fh);
显然它有效,但需要太长时间(真的太多)。

请问,最快的方法是什么?

还赞赏linux命令行(CentOS,如果可能的话)的解决方案

谢谢!

1 个答案:

答案 0 :(得分:1)

如果您的匹配项已找到并写在最终的CSV中,则应使用break;

if ($ref == $refe) {
    echo "$ref equal to $refe ! \n";
    $stringData = "$arr[0];$arr[1];$arr[2];$arr[3];$arr[4];$arr[5];$arr[6];$arr[7];$arr[8];$arr[9];$arr[10];$arr[11];$brr[0];$brr[1];$brr[2];$brr[3];$brr[4];$brr[5];$brr[6];$brr[7];$brr[8];$brr[9];$brr[10];$brr[11];$brr[12];$brr[13]";  
    $stringData = str_replace(array("\r","\n"),"",$stringData);
    $stringData .= PHP_EOL;
    fwrite($fh, $stringData);
    break; // break the loop here for unwanted cycles
}

此外,如果你使用$lined数组中的一行,那么你可以取消设置它,这样你的$lined数组就会很短,而你的第二个循环会迭代得更少。 在使用break;

之前,请使用以下行
unset($lined[$fine_num]);

您的第二个循环可以像

一样进行优化
foreach ($lined as $fine_num => $fine) { 
    $brr = explode(";",$fine);
    $refe = $brr[1];
    $refe = rtrim($refe);
    echo "$refe \n";
    if ($ref == $refe) {
        echo "$ref equal to $refe ! \n";
        $stringData = "$arr[0];$arr[1];$arr[2];$arr[3];$arr[4];$arr[5];$arr[6];$arr[7];$arr[8];$arr[9];$arr[10];$arr[11];$brr[0];$brr[1];$brr[2];$brr[3];$brr[4];$brr[5];$brr[6];$brr[7];$brr[8];$brr[9];$brr[10];$brr[11];$brr[12];$brr[13]";  
        $stringData = str_replace(array("\r","\n"),"",$stringData);
        $stringData .= PHP_EOL;
        fwrite($fh, $stringData); 
        unset($lined[$fine_num]); // unset so that next time loop will interate less
        break; // break here
    }
}