Перезаписать строку в файле с помощью PHP - PullRequest
17 голосов
/ 25 октября 2008

Каков наилучший способ перезаписать определенную строку в файле? В основном я хочу найти в файле строку '@parsethis' и перезаписать оставшуюся часть этой строки чем-то другим.

Ответы [ 7 ]

20 голосов
/ 25 октября 2008

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

$source='in.txt';
$target='out.txt';

// copy operation
$sh=fopen($source, 'r');
$th=fopen($target, 'w');
while (!feof($sh)) {
    $line=fgets($sh);
    if (strpos($line, '@parsethis')!==false) {
        $line='new line to be inserted' . PHP_EOL;
    }
    fwrite($th, $line);
}

fclose($sh);
fclose($th);

// delete old source file
unlink($source);
// rename target file to source file
rename($target, $source);
18 голосов
/ 25 октября 2008

Если файл не слишком большой, вероятно, лучшим способом будет прочитать файл в массив строк с помощью file () , найти в массиве строк свою строку и отредактировать ее. строка, затем implode () массив обратно и fwrite () обратно в файл.

5 голосов
/ 25 октября 2008

Ваша главная проблема заключается в том, что новая строка может не иметь такую ​​же длину, как старая. Если вам нужно изменить длину строки, нет никакого способа переписать хотя бы весь файл после измененной строки. Самый простой способ - создать новый, измененный файл, а затем переместить его поверх оригинала. Таким образом, для читателей всегда доступен полный файл. Используйте блокировку, чтобы убедиться, что только один скрипт изменяет файл одновременно, и, поскольку вы собираетесь заменить файл, сделайте блокировку для другого файла. Выезд flock().

Если вы уверены, что длина новой строки будет такой же, как и у старой строки, вы можете открыть файл в режиме чтения / записи (используйте r+ в качестве второго аргумента для fopen()) и вызовите ftell() чтобы сохранить позицию, строка начинается каждый раз, прежде чем вы наберете fgets(), чтобы прочитать строку. Как только вы найдете строку, которую хотите перезаписать, вы можете использовать fseek() для возврата к началу строки и fwrite() новые данные. Один из способов заставить линию всегда иметь одинаковую длину - это разместить ее на максимально возможной длине.

0 голосов
/ 16 апреля 2019

Если вы хотите полностью заменить содержимое одного файла содержимым другого файла, вы можете использовать это:

rename("./some_path/data.txt", "./some_path/data_backup.txt");
rename("./some_path/new_data.txt", "./some_path/data.txt");

Таким образом, в первой строке вы создаете резервную копию файла, а во второй строке вы заменяете файл содержимым нового файла.

Насколько я могу судить, переименование возвращает логическое значение. True, если переименование прошло успешно, и false, если не удалось. Следовательно, второй этап можно запустить только в том случае, если первый этап выполнен успешно, чтобы предотвратить перезапись файла, если резервное копирование не было выполнено успешно. Проверить:

https://www.php.net/manual/en/function.rename.php

Надеюсь, это кому-нибудь пригодится.

Приветствия

Адриан

0 голосов
/ 14 ноября 2018

Это решение, которое работает для перезаписи только одной строки файла с помощью sed из PHP. Мой файл содержит только стили и форматируется: $ styleVarName: styleVarProperty; \ n
Для этого я сначала добавляю «:» в конец myStyleVarName, а sed заменяет остальную часть этой строки новым свойством и добавляет точку с запятой. Убедитесь, что в myStyleVarProp правильно экранированы символы.

$command = "pathToShellScript folder1Name folder2Name myStyleVarName myStyleVarProp";
shell_exec($command);

/* shellScript */
#!/bin/bash
file=/var/www/vhosts/mydomain.com/$1/$2/scss/_variables.scss
str=$3"$4"
sed -i "s/^$3.*/$str;/" $file
0 голосов
/ 25 октября 2008

или если ваш файл не слишком большой:

$sample = file_get_contents('sample');
$parsed =preg_replace('#@parsethis.*#', 'REPLACE TO END OF LINE', $sample);

Вам нужно будет выбрать разделители '#', которых нет в файле.

0 голосов
/ 25 октября 2008

Скорее всего, я бы сделал то, что предложил Джереми, но просто для альтернативного способа сделать это здесь есть другое решение. Это не было проверено или использовано и предназначено для * nix систем.

$cmd = "grep '@parsethis' " . $filename;
$output = system($cmd, $result);
$lines = explode("\n", $result);
// Read the entire file as a string
// Do a str_repalce for each item in $lines with ""
...