1

我需要一个脚本来查找并替换类似 CSV 文件中的 sertain 行。该文件如下所示:

 18:110327,98414,127500,114185,121701,89379,89385,89382,92223,89388,89366,89362,89372,89369
 21:82297,79292,89359,89382,83486,99100
 98:110327,98414,127500,114185,121701

24:82297,79292,89359,89382,83486,99100

现在我需要更改第 21 行。

这是我到目前为止得到的。

前 2 到 4 位数字后跟 : 是类别编号。此之后的每个数字(后跟一个 ,)都是一个页面的 id。我从数据库中获取我想要的 id(即 82297 等)。

 //test 2
 $sQry = "SELECT * FROM artikelen WHERE adviesprijs <>''";

$rQuery = mysql_query ($sQry);

 if ( $rQuery === false )
{
 echo  mysql_error ();
 exit ;
 }

$aResult = array ();

while ( $r = mysql_fetch_assoc ($rQuery) )
{

$aResult[] = $r['artikelid'];


}






$replace_val_dirty = join(",",$aResult);

$replace_val= "21:".$replace_val_dirty;




// file location
$file='../../data/articles/index.lst';

// read the file index.lst
$file1 = file_get_contents($file);

 //strip eerde artikel id van index.lst
 $file3='../../data/articles/index_grp21.lst';

$file3_contents = file_get_contents($file3);


$file2 = str_replace($file3_contents, $replace_val, $file1);






if (file_exists($file)) {
echo "The file $filename exists";
} else {
echo "The file $filename does not exist";

 }

 if (file_exists($file3)) {
echo "The file $filename exists";
} else {
echo "The file $filename does not exist";

 }



 // replace the data
 $file_val = $file2;
 // write the file
 file_put_contents($file, $file_val);


 //write index_grp98.lst

file_put_contents($file3, $replace_val);

mail('info@', 'Aanbieding catergorie geupdate', 'Aanbieding catergorie  geupdate');

谁能指出我正确的方向来做到这一点?任何帮助,将不胜感激。

4

1 回答 1

2

您需要打开原始文件并浏览每一行。当您发现要更改的行时,请更改该行。

由于您在执行此操作时无法编辑文件,因此您在执行此操作时编写了一个临时文件,因此您逐行复制,如果该行需要更改,则更改该行。

完成整个文件后,将临时文件复制到原始文件。

示例代码:

$path = 'file';

$category = 21;
$articles = [111182297, 79292, 89359, 89382, 83486, 99100];

$prefix    = $category . ':';
$prefixLen = strlen($prefix);
$newLine   = $prefix . implode(',', $articles);

这部分只是设置基础:类别、文章的 ID,然后构建相关的字符串。

现在打开文件以更改以下行:

$file = new SplFileObject($path, 'r+');
$file->setFlags(SplFileObject::DROP_NEW_LINE | SplFileObject::SKIP_EMPTY);
$file->flock(LOCK_EX);

该文件被锁定,因此在文件被更改时没有其他进程可以编辑该文件。在该文件旁边,还需要临时文件:

$temp = new SplTempFileObject(4096);

设置好这两个文件后,让我们遍历其中的每一行$file并比较是否需要替换:

foreach ($file as $line) {
    $isCategoryLine = substr($line, 0, $prefixLen) === $prefix;
    if ($isCategoryLine) {
        $line = $newLine;
    }
    $temp->fwrite($line."\n");
}

现在$temporary 文件已经包含了更改的行。请注意,我使用了 UNIX 类型的 EOF(行尾)字符 ( \n),具体取决于您的具体文件类型,这可能会有所不同。

所以现在,需要将临时文件复制到原始文件中。让我们倒回文件,截断它,然后再次写入所有行:

$file->seek(0);
$file->ftruncate(0);
foreach ($temp as $line) {
    $file->fwrite($line);
}

最后你需要解除锁定:

$file->flock(LOCK_UN);

就是这样,在 中$file,该行已被替换。

立即举例:

$path = 'file';

$category = 21;
$articles = [111182297, 79292, 89359, 89382, 83486, 99100];

$prefix    = $category . ':';
$prefixLen = strlen($prefix);
$newLine   = $prefix . implode(',', $articles);

$file = new SplFileObject($path, 'r+');
$file->setFlags(SplFileObject::DROP_NEW_LINE | SplFileObject::SKIP_EMPTY);
$file->flock(LOCK_EX);

$temp = new SplTempFileObject(4096);

foreach ($file as $line) {
    $isCategoryLine = substr($line, 0, $prefixLen) === $prefix;
    if ($isCategoryLine) {
        $line = $newLine;
    }
    $temp->fwrite($line."\n");
}

$file->seek(0);
$file->ftruncate(0);
foreach ($temp as $line) {
    $file->fwrite($line);
}

$file->flock(LOCK_UN);

应该适用于 PHP 5.2 及更高版本,我使用 PHP 5.4 数组语法, 如果您使用的是 PHP 5.2 / 5.3 ,您可以[111182297, ...] 替换为。array(111182297, ...)

于 2012-09-23T21:21:00.113 回答