Вопрос

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

Это было полезно?

Решение

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

Другие советы

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

$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);

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

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

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

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

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

Это решение, которое работает для перезаписи только одной строки файла с помощью 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

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

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

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

Ваше здоровье

Адриан

Скорее всего, я бы сделал то, что предложил Джереми, но просто для альтернативного способа сделать это здесь - другое решение. Это не было проверено или использовано и предназначено для * 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 ""
Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top