在PHP中基于CSV2查找和替换CSV1中的列

时间:2018-04-28 23:40:06

标签: php

我正在尝试替换列的值"关闭"在第一个CSV中,列值为#34; LTP"在第二个CSV中,CSV2和CSV1中的以下列应相同:

"符号= SYMBOL","日期= TIMESTAMP","到期= EXPIRY_DT","选项类型= OPTION_TYP",&# 34;行使价= STRIKE_PR"

以下是CSV1的当前结构:

INSTRUMENT  SYMBOL  EXPIRY_DT   STRIKE_PR   OPTION_TYP  OPEN    HIGH    LOW CLOSE   SETTLE_PR   CONTRACTS   VAL_INLAKH  OPEN_INT    CHG_IN_OI   TIMESTAMP
OPTSTK  INFY    26-Apr-18   780 CE  0   0   0   408.6   361.05  0   0   0   0   2-Apr-18
OPTSTK  INFY    26-Apr-18   800 CE  0   0   0   388.95  341.15  0   0   0   0   2-Apr-18
OPTSTK  INFY    26-Apr-18   820 CE  0   0   0   369.35  321.25  0   0   0   0   2-Apr-18
OPTSTK  INFY    26-Apr-18   840 CE  0   0   0   349.75  301.35  0   0   0   0   2-Apr-18
OPTSTK  INFY    26-Apr-18   860 CE  0   0   0   330.2   281.45  0   0   0   0   2-Apr-18
OPTSTK  INFY    26-Apr-18   880 CE  0   0   0   310.75  261.55  0   0   0   0   2-Apr-18
OPTSTK  INFY    26-Apr-18   900 CE  0   0   0   291.35  241.65  0   0   0   0   2-Apr-18
OPTSTK  INFY    26-Apr-18   920 CE  0   0   0   272.15  221.75  0   0   0   0   2-Apr-18
OPTSTK  INFY    26-Apr-18   940 CE  0   0   0   216 201.85  0   0   5400    0   2-Apr-18
OPTSTK  INFY    26-Apr-18   960 CE  0   0   0   234.45  181.95  0   0   0   0   2-Apr-18
OPTSTK  INFY    26-Apr-18   980 CE  0   0   0   216.1   162.1   0   0   0   0   2-Apr-18
OPTSTK  INFY    26-Apr-18   1000    CE  0   0   0   136 142.3   0   0   24600   0   2-Apr-18

CSV2的结构是:

Symbol   Date    Expiry  Option Type     Strike Price    Open    High    Low     Close   LTP     Settle Price    No. of contracts    Turnover in Lacs    Premium Turnover in Lacs    Open Int    Change in OI    Underlying Value
INFY    2-Apr-18    26-Apr-18   CE  780 0   0   0   408.6   0   361.05  0   0   0   0   0   1137.15
INFY    2-Apr-18    26-Apr-18   CE  1380    1   1   1   1   1   1   1   8.29    0.01    600 600 1137.15
INFY    2-Apr-18    26-Apr-18   CE  820 0   0   0   369.35  0   321.25  0   0   0   0   0   1137.15
INFY    2-Apr-18    26-Apr-18   CE  840 0   0   0   349.75  0   301.35  0   0   0   0   0   1137.15
INFY    2-Apr-18    26-Apr-18   CE  860 0   0   0   330.2   0   281.45  0   0   0   0   0   1137.15
INFY    2-Apr-18    26-Apr-18   CE  880 0   0   0   310.75  0   261.55  0   0   0   0   0   1137.15
INFY    2-Apr-18    26-Apr-18   CE  900 0   0   0   291.35  0   241.65  0   0   0   0   0   1137.15
INFY    2-Apr-18    26-Apr-18   CE  920 0   0   0   272.15  0   221.75  0   0   0   0   0   1137.15
INFY    2-Apr-18    26-Apr-18   CE  940 0   0   0   216 216 201.85  0   0   0   5400    0   1137.15
INFY    2-Apr-18    26-Apr-18   CE  960 0   0   0   234.45  0   181.95  0   0   0   0   0   1137.15
INFY    2-Apr-18    26-Apr-18   CE  980 0   0   0   216.1   0   162.1   0   0   0   0   0   1137.15
INFY    2-Apr-18    26-Apr-18   CE  1000    0   0   0   136 134 142.3   0   0   0   24600   0   1137.15
INFY    2-Apr-18    26-Apr-18   CE  1020    0   0   0   126 126 122.65  0   0   0   1200    0   1137.15

1 个答案:

答案 0 :(得分:0)

关于CSV和一般任何文件的一些内容

  

我正在尝试替换列的值"关闭"在第一个CSV中,列值为#34; LTP"在第二个CSV中的以下列。

你不能"取代"文件中的任何内容。但是,您可以使用fgetcsv从文件中提取数据,然后使用fputcsv更改它并使用更改的数据编写新文件。

如你所示"没有代码",我不打算写太多。但我会继续讨论这个过程。

  1. 使用其中的新值(完全)读入文件,从中创建一个数组
  2. 读入您希望逐行更改的文件
  3. 对于第二个文件的每一行,在第一个文件(数组)中找到正确的行,并在文件#2(您的文件#1)中更新该行的数据
  4. 写一个包含更新数据的新文件。
  5. 您必须阅读要在最后更改数据的文件,因为您希望保留该文件中行的顺序,而且这样更容易。
  6. 用于匹配数据的提示。当您在文件#1中读取时,请使用您需要匹配的字段并使用md5对它们进行哈希处理。 Md5真的很快就达到了每秒500万次哈希的速度(是的,我定时)

    $time = microtime(true);
    
    for($i=0; $i <= 5000000; ++$i){
        md5("hello world");
    }
    
    echo "Complete :".number_format((microtime(true) - $time), 4);
    

    试试yourself

    输出

    Complete :1.3057
    

    现在这与安全性或其他任何事情无关,我会在一秒钟内解释。

    构建数组时(步骤1),取出要匹配的字段并对其进行哈希处理,并将其用于数组中的键。

      $hash = md5(
          $row['Symbol'] .
          strtotime($row['Date']) . //convert to timestamp
          $row['Expiry'] .
          $row['Option Typ'] .
          $row['Strike Price']
      );
    
      $data[$hash] = $row;
    

    然后在读取第二个文件(要修改的文件)时执行相同的操作

     $newHash = md5(
          $row['SYMBOL'] .
          TIMESTAMP . //convert to timestamp
          $row['EXPIRY_DT'] .
          $row['OPTION_TYP'] .
          $row['STRIKE_PR'] .
      );
    

    然后只需查看$data数组isset($data[$newHash])中的哈希值即可查看您正在修改的文件。一旦找到包含该数据的行,您需要的其余部分非常简单。

    现在读取文件的基本方法是

      $h = fopen('filename.csv', 'r');
      $data = [];
    
      $headers = false;
      while(!feof($h)){
          $row = fgetcsv($h);
          if(!$headers) $headers = $row;
    
          $row = array_combine($headers, $row);
          //do the hash "and other stuff" 
          $data[$hash] = $row;
      }
    

    然后在完成之后读取另一个文件,使用相同类型的循环,执行散列,匹配所需的数据,更新旧数据,将行写入新的(第3个)文件等...

    要使哈希工作,数据必须匹配从一个CSV到另一个(显然),不能重复&#34;哈希&#34;行。行的数据散列相同但在其他字段中具有值。就像你在同一个文件中有两行哈希相同,然后Close值不同。无论如何,这都会给你带来麻烦。

    祝你好运,查阅一些关于如何处理CSV文件的教程,其中有很多文件。