Sto cercando di eseguire una sostituzione di stringa per l'intero file in PHP. Il mio file ha più di 100 MB, quindi devo andare linea per riga e non posso usare file_get_contents()
. C'è una buona soluzione a questo?stringa di sostituzione in un file di grandi dimensioni con php
risposta
Se non si richiede l'utilizzo di PHP, si consiglia vivamente di eseguire operazioni di questo tipo dalla riga di comando. È di gran lunga lo strumento migliore per il lavoro e molto più facile da usare.
In ogni caso, il comando sed
è quello che state cercando:
sed s/search/replace oldfilename > newfilename
Se avete bisogno della cassa-insensibilità:
sed -i s/search/replace oldfilename > newfilename
Se avete bisogno di questo per eseguire in modo dinamico all'interno PHP, è possibile utilizzare passthru()
:
$output = passthru("sed s/$search/$replace $oldfilename > $newfilename");
perché 'passthru()' e non 'exec()'? – Brian
Entrambi funzionerebbero, ma usando il passthru, è possibile ottenere l'intero output. exec restituisce solo l'ultima riga dell'output. –
non è così facile da usare passthru per chiamare sed, vedere la mia risposta per i dettagli. –
Farlo poche righe alla volta, scaricare la variabile, ottenere le righe successive.
$fh = fopen("bigfile.txt", "flags");
$num = 0;
$length = 300;
$filesize = filesize("bigfile.txt");
while($num < $filesize)
{
$contents = fread($fh, $length);
// .. do stuff ...
$num = $num+$length;
fseek($fh, $num);
}
fclose($fh);
Si desidera assicurarsi che sia corretto (non testato). Vedi la biblioteca su PHP Documentation.
La parte difficile sta per essere scritta sul file. La prima idea che mi viene in mente è sostituire la stringa, scrivere il nuovo contenuto in un altro file e alla fine eliminare il vecchio file e sostituirlo con quello nuovo.
sì, è giusto ... lo streaming di un povero.Che efficacemente avrebbe funzionato se lo avessi fatto sulla riga di comando: cat file | sed 's/replace/something/g'> output.file – mlathe
Avrei eseguito uno script php che ha chiamato la funzione riga di comando - quindi stampato il file di output :) – Dirk
Questo metodo ha un problema se la stringa che stai cercando sostituire è più lungo di un singolo carattere. È abbastanza probabile che la stringa possa estendersi su più blocchi di dati, causando la possibilità di saltare la sostituzione. – bish
Qui si va:
function replace_file($path, $string, $replace)
{
set_time_limit(0);
if (is_file($path) === true)
{
$file = fopen($path, 'r');
$temp = tempnam('./', 'tmp');
if (is_resource($file) === true)
{
while (feof($file) === false)
{
file_put_contents($temp, str_replace($string, $replace, fgets($file)), FILE_APPEND);
}
fclose($file);
}
unlink($path);
}
return rename($temp, $path);
}
chiamare in questo modo:
replace_file('/path/to/fruits.txt', 'apples', 'oranges');
Immagino solo che tu abbia questa funzione in giro? –
@ Chacha102: No, l'ho appena codificato. Perché? –
Era una specie di barzelletta. Non so perché sarebbe stato divertente. Lo darò al nostro JDT (Joke Development Team) e ti ricontatterò tra 6 e 8 settimane. –
qualcosa di simile?
$infile="file";
$outfile="temp";
$f = fopen($infile,"r");
$o = fopen($outfile,"a");
$pattern="pattern";
$replace="replace";
if($f){
while(!feof($f)){
$line = fgets($f,4096);
if (strpos($pattern,"$line") !==FALSE){
$line=str_replace($pattern,$replace,$line);
}
fwrite($o,$line);
}
}
fclose($f);
fclose($o);
rename($outfile,$infile);
Avrei usato "sed" in un modo più esplicito, quindi sei meno dipendente dal tuo sistema.
$output = passthru("sed -e 's/$search/$replace/g' $oldfilename > $newfilename");
Se non è possibile utilizzare direttamente sed da linea di comando, perché è un compito dinamico ed è necessario chiamare da php è difficile ottenere il giusto sintassi: si deve fuggire in modi diversi nella ricerca e sostituzione stringhe questi personaggi
'/$ . * [ ] \^&
la seguente funzione di ricerca e sostituzione di una stringa in un file senza interpretare la stringa cercata come un'espressione regolare. Quindi, se lo si desidera, è possibile cercare la stringa ". *" E sostituirla con "$".
/**
* str_replace_with_sed($search, $replace, $file_in, $file_out=null)
*
* Search for the fixed string `$search` inside the file `$file_in`
* and replace it with `$replace`. The replace occurs in-place unless
* `$file_out` is defined: in that case the resulting file is written
* into `$file_out`
*
* Return: sed return status (0 means success, any other integer failure)
*/
function str_replace_with_sed($search, $replace, $file_in, $file_out=null)
{
$cmd_opts = '';
if (! $file_out)
{
// replace inline in $file_in
$cmd_opts .= ' -i';
}
// We will use Basic Regular Expressions (BRE). This means that in the
// search pattern we must escape
// $.*[\]^
//
// The replacement string must have these characters escaped
// \ &
//
// In both cases we must escape the separator character too (usually /)
//
// Since we run the command trough the shell we We must escape the string
// too (yai!). We're delimiting the string with single quotes (') and we'll
// escape them with '\'' (close string, write a single quote, reopen string)
// Replace all the backslashes as first thing. If we do it in the following
// batch replace we would end up with bogus results
$search_pattern = str_replace('\\', '\\\\', $search);
$search_pattern = str_replace(array('$', '.', '*', '[', ']', '^'),
array('\\$', '\\.', '\\*', '\\[', '\\]', '\\^'),
$search_pattern);
$replace_string = str_replace(array('\\', '&'),
array('\\\\', '\\&'),
$replace);
$output_suffix = $file_out ? " > '$file_out' " : '';
$cmd = sprintf("sed ".$cmd_opts." -e 's/%s/%s/g' \"%s\" ".$output_suffix,
str_replace('/','\\/', # escape the regexp separator
str_replace("'", "'\''", $search_pattern) // sh string escape
),
str_replace('/','\\/', # escape the regexp separator
str_replace("'", "'\''", $replace_string) // sh string escape
),
$file_in
);
passthru($cmd, $status);
return $status;
}
- 1. Scompattiamo file di grandi dimensioni con gzip in PHP
- 2. Come base64 decodificare file di grandi dimensioni in PHP
- 3. File JSON di grandi dimensioni
- 4. Trova e sostituisci in un file di grandi dimensioni
- 5. Caricamenti di file di grandi dimensioni
- 6. Caricamento file di grandi dimensioni con WebSocket
- 7. PHP readfile() e download di grandi dimensioni
- 8. Ottimizzazione di ricerca e sostituzione su file di grandi dimensioni in Python
- 9. Modifica di un file di grandi dimensioni in Scala
- 10. Leggi file di grandi dimensioni in parallelo?
- 11. Leggere file di grandi dimensioni in Java
- 12. Python: HTTP Pubblica un file di grandi dimensioni con streaming
- 13. Supporto file di grandi dimensioni in C++
- 14. Come gestire griglie stringa di grandi dimensioni?
- 15. Elaborazione di file xlsx di grandi dimensioni
- 16. CodeIgniter Caricamento di file di grandi dimensioni
- 17. Corrispondenza di una stringa in un file di testo di grandi dimensioni?
- 18. Elaborazione di file xml di grandi dimensioni
- 19. Ricerca in file di grandi dimensioni con ifstream
- 20. Serve file di grandi dimensioni (con carichi elevati) in Django
- 21. PDFbox caricamento di file di grandi dimensioni
- 22. Esperienza con PHP QuickHash per array di grandi dimensioni
- 23. Apertura Un file JSON di grandi dimensioni in Python
- 24. C# ricerca di file di testo di grandi dimensioni
- 25. Mapping stringa di grandi dimensioni con Fluent NHibernate
- 26. Sostituzione di {{string}} all'interno del file php
- 27. Leggere un file di grandi dimensioni in righe di stringa OCaml
- 28. Prestazioni di Windows fsync (FlushFileBuffers) con file di grandi dimensioni
- 29. Efficace caricamento di file di grandi dimensioni con Yesod
- 30. Caricamento di file di grandi dimensioni con Python/Django
È necessario utilizzare PHP? Se si ha accesso alla riga di comando, è possibile utilizzare il comando 'sed' per eseguire questa stessa funzione, probabilmente con un mal di testa molto inferiore. Se ha bisogno di essere automatizzato, puoi creare uno script di shell che gira su cron. –
D'accordo, questo è qualcosa per la riga di comando, non per PHP. – Mike