Pregunta

¿Cuál es la mejor manera de sobrescribir una línea específica en un archivo? Básicamente quiero buscar un archivo para la cadena '@parsethis' y sobrescribir el resto de esa línea con otra cosa.

¿Fue útil?

Solución

Si el archivo no es demasiado grande, la mejor manera sería leer el archivo en una matriz de líneas con el archivo () , busque en la matriz de líneas su cadena y edítela, luego implode () la matriz se vuelve a unir y fwrite () para volver al archivo.

Otros consejos

Si el archivo es realmente grande (archivos de registro o algo así) y está dispuesto a sacrificar la velocidad por el consumo de memoria, puede abrir dos archivos y esencialmente hacer el truco Jeremy Ruten propuesto mediante el uso de archivos en lugar de la memoria del sistema.

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

Su principal problema es el hecho de que la nueva línea puede no tener la misma longitud que la línea anterior. Si necesita cambiar la longitud de la línea, no hay forma de reescribir al menos todo el archivo después de la línea cambiada. La forma más fácil es crear un nuevo archivo modificado y luego moverlo sobre el original. De esta manera hay un archivo completo disponible en todo momento para los lectores. Utilice el bloqueo para asegurarse de que solo una secuencia de comandos modifique el archivo a la vez y, como va a reemplazar el archivo, realice el bloqueo en un archivo diferente. Echa un vistazo a flock () .

Si está seguro de que la nueva línea tendrá la misma longitud que la línea anterior, puede abrir el archivo en modo de lectura / escritura (use r + como segundo argumento para fopen () ) y llame a ftell () para guardar la posición en que comienza la línea cada vez antes de llamar a fgets () para leer una línea. Una vez que encuentre la línea que desea sobrescribir, puede usar fseek () para volver al principio de la línea y fwrite () los nuevos datos. Una forma de forzar que la línea tenga siempre la misma longitud es espaciarla hasta la longitud máxima posible.

o si su archivo no es demasiado grande:

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

Sin embargo, deberá elegir delimitadores '#' que no están presentes en el archivo.

Esta es una solución que funciona para reescribir solo una línea de un archivo con PHP desde PHP. Mi archivo contiene solo vars de estilo y está formateado: $ styleVarName: styleVarProperty; \ n
Para esto primero añado el ": " a los extremos de myStyleVarName, y sed reemplaza el resto de esa línea con la nueva propiedad y agrega un punto y coma. Asegúrese de que los caracteres se escapen correctamente en 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

Si desea reemplazar completamente el contenido de un archivo con el contenido de otro archivo, puede usar esto:

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

Así que en la primera línea haces una copia de seguridad del archivo y en la segunda, reemplazas el archivo con el contenido de un nuevo archivo.

Por lo que puedo decir, el cambio de nombre devuelve un valor booleano. Verdadero si el cambio de nombre es exitoso y falso si falla. Por lo tanto, solo se puede ejecutar el segundo paso si el primer paso es exitoso para evitar sobrescribir el archivo a menos que se haya realizado una copia de seguridad correctamente. Echa un vistazo a:

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

Espero que sea útil para alguien.

Saludos

Adrian

Lo más probable es que haga lo que sugirió Jeremy, pero solo por una forma alternativa de hacerlo aquí es otra solución. Esto no ha sido probado o usado y es para sistemas * 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 ""
Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top