Domanda

Qual è il modo migliore per sovrascrivere una riga specifica in un file? Fondamentalmente voglio cercare un file per la stringa "@parsethis" e sovrascrivere il resto di quella riga con qualcos'altro.

È stato utile?

Soluzione

Se il file non è troppo grande, il modo migliore sarebbe probabilmente quello di leggere il file in una matrice di righe con il file () , cerca nell'array di righe la stringa e modifica quella riga, quindi implode () l'array torna insieme e fwrite () torna al file.

Altri suggerimenti

Se il file è davvero grande (file di registro o qualcosa del genere) e sei disposto a sacrificare la velocità per il consumo di memoria, potresti aprire due file e sostanzialmente fare il trucco Jeremy Ruten proposto utilizzando i file anziché la memoria di 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);

Il tuo problema principale è il fatto che la nuova linea potrebbe non avere la stessa lunghezza della vecchia linea. Se è necessario modificare la lunghezza della riga, non è possibile uscire dalla riscrittura almeno del file dopo la modifica della riga. Il modo più semplice è creare un nuovo file modificato e quindi spostarlo sull'originale. In questo modo è sempre disponibile un file completo per i lettori. Utilizzare il blocco per assicurarsi che solo uno script stia modificando il file alla volta e, poiché si intende sostituire il file, eseguire il blocco su un altro file. Dai un'occhiata a flock () .

Se si è certi che la nuova riga avrà la stessa lunghezza della riga precedente, è possibile aprire il file in modalità lettura / scrittura (utilizzare r + come secondo argomento per fopen () ) e chiama ftell () per salvare la posizione in cui inizia la linea ogni volta prima di chiamare fgets () per leggere una linea. Una volta trovata la riga che si desidera sovrascrivere, è possibile utilizzare fseek () per tornare all'inizio della riga e fwrite () i nuovi dati. Un modo per forzare la linea ad avere sempre la stessa lunghezza è di spaziare fino alla massima lunghezza possibile.

o se il tuo file non è troppo grande:

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

Dovrai scegliere i delimitatori '#' che non sono presenti nel file.

Questa è una soluzione che funziona per riscrivere solo una riga di un file in atto con sed da PHP. Il mio file contiene solo vari stili ed è formattato: $ styleVarName: styleVarProperty; \ n
Per questo aggiungo prima il ": " alle estremità di myStyleVarName e sed sostituisce il resto di quella riga con la nuova proprietà e aggiunge un punto e virgola. Assicurati che i caratteri siano salvati correttamente in 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

Se si desidera sostituire completamente il contenuto di un file con il contenuto di un altro file, è possibile utilizzare questo:

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

Quindi nella prima riga esegui il backup del file e nella seconda riga sostituisci il file con il contenuto di un nuovo file.

Per quanto ne so, la ridenominazione restituisce un valore booleano. Vero se la ridenominazione ha esito positivo e falso in caso contrario. Pertanto, è possibile eseguire il secondo passaggio solo se il primo passaggio riesce a impedire la sovrascrittura del file a meno che non sia stato eseguito correttamente un backup. Dai un'occhiata:

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

Spero che sia utile a qualcuno.

Saluti

Adrian

Molto probabilmente farei ciò che Jeremy ha suggerito, ma solo per un modo alternativo di farlo qui è un'altra soluzione. Questo non è stato testato o utilizzato ed è per i sistemi * 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 ""
Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top