删除TXT文件中的特定行

时间:2018-04-18 21:17:21

标签: php

我有一个包含数百万行文字的.txt文件

下面的代码删除.txt文件中的特定行(.com域名)。但是大文件无法做到:(

<?php 
$fname = "test.txt";
$lines = file($fname);
foreach($lines as $line) if(!strstr($line, ".com")) $out .= $line; 
$f = fopen($fname, "w"); 
fwrite($f, $out); 
fclose($f); 
?> 

我想删除某些行并将它们放在另一个文件中

例如,网站的域名列表。切断.com域并将其粘贴到另一个文件中......

3 个答案:

答案 0 :(得分:0)

这是一种使用http://php.net/manual/en/class.splfileobject.php并使用临时文件的方法。

$fileName = 'whatever.txt';
$linesToDelete = array( 3, 5 );

// Working File
$file = new SplFileObject( $fileName, 'a+' );
$file->flock( LOCK_EX );
// Temp File
$temp = new SplTempFileObject( 0 );
$temp->flock( LOCK_EX );
// Wite the temp file without the lines
foreach( $file as $key => $line )
{
  if( in_array( $key + 1, $linesToDelete ) === false )
  {
    $temp->fwrite( $line );
  }
}
// Write Back to the main file
$file->ftruncate(0);
foreach( $temp as $line )
{
  $file->fwrite( $line );
}
$file->flock( LOCK_UN );
$temp->flock( LOCK_UN );

虽然这可能很慢,但是在我的Windows xampp设置上,一个40兆的文件和140000行需要2.3秒。这可以通过写入临时文件并执行文件移动来加速,但我不想在您的环境中踩到文件权限。

编辑:使用重命名/移动而非第二次写入的解决方案

$fileName = __DIR__ . DIRECTORY_SEPARATOR . 'whatever.txt';
$linesToDelete = array( 3, 5 );

// Working File
$file = new SplFileObject( $fileName, 'a+' );
$file->flock( LOCK_EX );
// Temp File
$tempFileName = tempnam( sys_get_temp_dir(), rand() );
$temp = new SplFileObject( $tempFileName,'w+');
$temp->flock( LOCK_EX );
// Write the temp file without the lines
foreach( $file as $key => $line )
{
  if( in_array( $key + 1, $linesToDelete ) === false )
  {
    $temp->fwrite( $line );
  }
}
// File Rename
$file->flock( LOCK_UN );
$temp->flock( LOCK_UN );
unset( $file, $temp ); // Kill the SPL objects relasing further locks
unlink( $fileName );
rename( $tempFileName, $fileName );

答案 1 :(得分:0)

可能是因为文件太大而占用了太多空间。 执行file('test.txt')时,它会将整个文件读入数组。 相反,您可以尝试使用Generators

GeneratorsExample.php

<?php
class GeneratorsExample {
    function file_lines($filename) {
        $file = fopen($filename, 'r'); 
        while (($line = fgets($file)) !== false) {
            yield $line; 
        } 
        fclose($file); 
    }

    function copyFile($srcFile, $destFile) {
        foreach ($this->file_lines($srcFile) as $line) {
            if(!strstr($line, ".com"))  {
                $f = fopen($destFile, "a"); 
                fwrite($f, $line); 
                fclose($f); 
            }
        }
 }
}

callingFile.php

<?php
    include('GeneratorsExample.php');
    $ob = new GeneratorsExample();
    $ob->copyFile('file1.txt', 'file2.txt')

答案 2 :(得分:-3)

虽然您可以使用数十行PHP代码,但一行shell代码可以使用。

$ grep Bar.com stuff.txt > stuff2.txt

或作为PHP

system ("grep Bar.com stuff.txt > stuff2.txt");