Найти строку и заменить несколько значений в большом текстовом файле с помощью PHP - PullRequest
0 голосов
/ 31 мая 2018

Я пытаюсь заменить определенные значения в большом текстовом файле с ок.60000 строк.Первый раз код выполняется нормально и заменяет значения, но в следующий раз он пропускает номера строк и добавляет новые значения в конец файла.

Я новичок в кодировании, поэтому мне может потребоваться расширенное руководство.

Линии, которые мне нужно изменить:

  1. MaxBytes[192.168.1.1]: 10000.Эта 1000 может быть любым числом, но IP-адрес здесь будет уникальным.Мне нужно изменить его MaxBytes [192.168.1.1]: 20000 (присвоенный номер);

  2. <TR><TD>Max Speed:</TD> <TD>200</TD></TR> Это 200 может быть любым числом.Я отслеживаю <TR><TD>IP Address:</TD><TD>192.168.1.1</TD></TR> строку и заменяю следующую строку, поскольку здесь IP-адрес уникален. Мне нужно изменить его на <TR><TD>Max Speed:</TD> <TD>500</TD></TR>

Образец Example.txt:

MaxBytes[192.168.1.1]: 10000
 <TABLE>
   <TR><TD>IP Address:</TD><TD>192.168.1.1</TD></TR>
   <TR><TD>Max Speed:</TD> <TD>300</TD></TR>
 </TABLE>

MaxBytes[192.168.1.2]: 30000
 <TABLE>
   <TR><TD>IP Address:</TD><TD>192.168.1.1</TD></TR>
   <TR><TD>Max Speed:</TD> <TD>300</TD></TR>
 </TABLE>

MaxBytes[192.168.1.3]: 10000
 <TABLE>
   <TR><TD>IP Address:</TD><TD>192.168.1.1</TD></TR>
   <TR><TD>Max Speed:</TD> <TD>200</TD></TR>
 </TABLE>

Вот коды, которые я использую

<?php
$dir = "Example.txt";
$search = "<TR><TD>IP Address:</TD><TD>192.168.1.1</TD></TR>";
$replacement = "   <TR><TD>Max Speed:</TD> <TD>500</TD></TR>";
$maxbytes = "MaxBytes[192.168.1.1]: ";
$new_line = "MaxBytes[192.168.1.1]: \r";
$newmaxbytes = "MaxBytes[192.168.1.1]: 20000";


///// Change Max Speed
function find_line_number_by_string($dir, $search, $case_sensitive=false ) {
        $line_number = '';
        if ($file_handler = fopen($dir, "r")) {
           $i = 0;
           while ($line = fgets($file_handler)) {
              $i++;
              //case sensitive is false by default
              if($case_sensitive == false) {    
                $search = strtolower($search); 
                $line = strtolower($line);      
              }
              //find the string and store it in an array
              if(strpos($line, $search) !== false){
                $line_number .=  $i.",";
              }
           }
           fclose($file_handler);
        }else{
            return "File not exists, Please check the file path or dir";
        }
        //if no match found
        if(count($line_number)){
            return substr($line_number, 0, -1);
        }else{
            return "No match found";
        }
    }

$line_number = find_line_number_by_string($dir, $search);
echo $line_number;

$lines = file($dir, FILE_IGNORE_NEW_LINES);
$lines[$line_number] = $replacement;
file_put_contents($dir , implode("\n", $lines));

///// Change MaxBytes

$contents = file_get_contents($dir);
$new_contents= "";
if( strpos($contents, $maxbytes) !== false) { // if file contains ID
    $contents_array = preg_split("/\\r\\n|\\r|\\n/", $contents);
    foreach ($contents_array as &$record) {    // for each line
        if (strpos($record, $maxbytes) !== false) { // if we have found the correct line
            $new_contents .= $new_line; // change record to new record
        }else{
            $new_contents .= $record . "\r";
        }
    }

file_put_contents($dir, $new_contents, LOCK_EX);

$fhandle = fopen($dir,"r");
$content = fread($fhandle,filesize($dir));
$content = str_replace($maxbytes, $newmaxbytes, $content);
$fhandle = fopen($dir,"w");
fwrite($fhandle,$content);
fclose($fhandle);

}else{}

?>

Ответы [ 2 ]

0 голосов
/ 31 мая 2018

Есть что-то не совсем понятное в вашем вопросе и коде, конечно, это может быть написано более оптимальным способом.
Однако, учитывая текущий код, которым вы делитесь, я полагаю, что этот измененный вариант вам нужен.

<?php
$dir = "Example.txt";
$search = "<TR><TD>IP Address:</TD><TD>192.168.1.1</TD></TR>";
$replacement = "   <TR><TD>Max Speed:</TD> <TD>10000</TD></TR>";
$maxbytes = "MaxBytes[192.168.1.1]: ";
$new_line = "MaxBytes[192.168.1.1]: \r";
$newmaxbytes = "MaxBytes[192.168.1.1]: 20000";


///// Change Max Speed
function find_line_number_by_string($dir, $search, $case_sensitive=false ) {
    $line_number = [];
    if ($file_handler = fopen($dir, "r")) {
        $i = 0;
        while ($line = fgets($file_handler)) {
            $i++;
            //case sensitive is false by default
            if($case_sensitive == false) {
                $search = strtolower($search);
                $line = strtolower($line);
            }
            //find the string and store it in an array
            if(strpos($line, $search) !== false){
                $line_number[] =  $i;
            }
        }
        fclose($file_handler);
    }else{
        return "File not exists, Please check the file path or dir";
    }

    return $line_number;
}

$line_number = find_line_number_by_string($dir, $search);
var_dump($line_number);


$lines = file($dir, FILE_IGNORE_NEW_LINES);
if(!empty($line_number)) {
    $lines[$line_number[0]] = $replacement;
}

file_put_contents($dir , implode("\n", $lines));

///// Change MaxBytes

$contents = file_get_contents($dir);
$new_contents= "";
if( strpos($contents, $maxbytes) !== false) { // if file contains ID
    $contents_array = preg_split("/\\r\\n|\\r|\\n/", $contents);
    foreach ($contents_array as &$record) {    // for each line
        if (strpos($record, $maxbytes) !== false) { // if we have found the correct line
            $new_contents .= $new_line; // change record to new record
        }else{
            $new_contents .= $record . "\n";
        }
    }

    file_put_contents($dir, $new_contents, LOCK_EX);

    $fhandle = fopen($dir,"r");
    $content = fread($fhandle,filesize($dir));
    $content = str_replace($maxbytes, $newmaxbytes, $content);
    $fhandle = fopen($dir,"w");
    fwrite($fhandle,$content);
    fclose($fhandle);

}else{}

?>

Если это не работает так, как вам нужно, пожалуйста, свяжитесь со мной, я обновлю ответ ..

0 голосов
/ 31 мая 2018

Это потому, что вы удаляете все новые строки, но не добавляете новые, только возврат каретки.

Исправьте, вставив в строку 58 следующее:

$new_contents .= $record . "\n";

Возврат каретки(\ r) переходит к следующей строке, но не заканчивает текущую.Для этого вам нужен перевод строки (\ n).После второго запуска кода PHP думает, что текстовый файл - это всего лишь одна строка текста.

...