Pergunta

O que é a melhor maneira de substituir uma linha específica em um arquivo? Basicamente, eu quero procurar um arquivo para a string '@parsethis' e substituir o resto da linha com outra coisa.

Foi útil?

Solução

Se o arquivo não é muito grande, a melhor maneira seria provavelmente para ler o arquivo em uma matriz de linhas com () , pesquisar o conjunto de linhas para a sua corda e editar essa linha, então implode () a matriz de volta juntos e fwrite () -lo de volta para o arquivo.

Outras dicas

Se o arquivo é muito grande (arquivos de log ou algo assim) e você está disposto a sacrificar a velocidade de consumo de memória que você poderia abrir dois arquivos e essencialmente fazer o truque Jeremy Ruten proposto usando arquivos em vez de memória do 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);

Seu principal problema é o fato de que a nova linha pode não ser o mesmo comprimento que a antiga linha. Se você precisar alterar o comprimento da linha, não há nenhuma maneira de sair de reescrever pelo menos todos o arquivo após a linha alterada. A maneira mais fácil é criar um arquivo novo, modificado e, em seguida, movê-lo sobre o original. Desta forma, não é um arquivo completo disponível em todos os momentos para os leitores. Use bloqueio para se certificar de que apenas um script é modificar o arquivo de uma vez, e uma vez que você está indo para substituir o arquivo, faça o bloqueio em um arquivo diferente. Confira flock().

Se você tiver certeza de que a nova linha será o mesmo comprimento que a linha de idade, você pode abrir o arquivo em modo de leitura / escrita (uso r+ como o segundo argumento para fopen()) e ftell() chamada para salvar a posição da linha começa em cada tempo antes de chamar fgets() para ler uma linha. Depois de encontrar a linha que você deseja substituir, você pode usar fseek() para voltar ao início da linha e fwrite() os novos dados. Uma maneira de forçar a linha a ser sempre o mesmo comprimento é para preencher o espaço-lo para o comprimento máximo possível.

ou se o arquivo não é muito grande:

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

Você terá que escolher delimitadores '#', que não estão presentes no arquivo embora.

Esta é uma solução que funciona para reescrever apenas uma linha de um arquivo no lugar com sed de PHP. Meu arquivo contém apenas estilo Vars e é formatado: $ StyleVarName: styleVarProperty; \ n
Por isso eu primeiro adicionar o ":" até os confins da myStyleVarName e substitui sed o resto dessa linha com a nova propriedade e acrescenta um ponto e vírgula. Fazer personagens certeza que estão devidamente escapou em 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 você quiser substituir completamente o conteúdo de um arquivo com o conteúdo de outro arquivo que você pode usar isto:

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

Assim, na primeira linha que você faça backup do arquivo e na segunda linha você substituir o arquivo com o conteúdo de um novo arquivo.

Tanto quanto eu posso dizer a renomeação retorna um booleano. Verdadeiro se a renomeação é bem sucedida e false se ele falhar. Pode-se, portanto, só executar a segunda etapa se o primeiro passo é bem sucedida para evitar substituindo o arquivo a menos que um backup foi feito com sucesso. Confira:

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

A esperança que seja útil para alguém.

Felicidades

Adrian

Eu provavelmente fazer o que Jeremy sugerido, mas apenas para uma forma alternativa de fazer isso aqui é uma outra solução. Este não foi testado ou usado e é para os 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 em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top