Como substituir uma string em um arquivo usando Perl

open close replace File::Slurp read_file write_file slurp $/ $INPUT_RECORD_SEPARATOR

Parabéns! Sua start-up acabou de ser comprada pela empresa Super Large. Agora você precisa substituir Copyright Start-Up por Copyright Super Large no arquivo README.txt

File::Slurp

Se você puder instalar o File::Slurp e se o arquivo não for muito grande para ocupar a memória do seu computador, então esta pode ser uma solução:

use strict;
use warnings;

use File::Slurp qw(read_file write_file);

my $filename = 'README.txt';

my $data = read_file $filename, {binmode => ':utf8'};
$data =~ s/Copyright Start-Up/Copyright Super Large/g;
write_file $filename, {binmode => ':utf8'}, $data;

A função read_file do File::Slurp vai ler o arquivo inteiro e colocar o conteúdo em uma única variável escalar. Ela assume que o arquivo não é muito grande.

Nós definimos binmode => ':utf8' para lidar corretamente com caracteres Unicode. Então uma substituição por regex é usada com o modificador /g para trocar globalmente todas as ocorrências de texto antigo pelo texto novo.

Então nós salvamos o conteúdo no mesmo arquivo, novamente usando binmode => ':utf8' para lidar corretamente com caracteres Unicode.

Substituir o conteúdo com Perl puro

Se você não puder instalar File::Slurp você pode implementar uma versão limitada de suas funções. Neste caso, o corpo principal do código é quase o mesmo, exceto que não passamos os parâmetros para abrir o arquivo no modo Unicode. Temos isto codificado nas próprias funções. Você pode ver como isto é feito nas chamadas para o open.

use strict;
use warnings;

my $filename = 'README.txt';

my $data = read_file($filename);
$data =~ s/Copyright Start-Up/Copyright Super Large/g;
write_file($filename, $data);
exit;

sub read_file {
    my ($filename) = @_;

    open my $in, '<:encoding(UTF-8)', $filename or die "Could not open '$filename' for reading $!";
    local $/ = undef;
    my $all = <$in>;
    close $in;

    return $all;
}

sub write_file {
    my ($filename, $content) = @_;

    open my $out, '>:encoding(UTF-8)', $filename or die "Could not open '$filename' for writing $!";;
    print $out $content;
    close $out;

    return;
}

Na função read_file definimos a variável $/ (que também é chamada $INPUT_RECORD_SEPARATOR) para undef. Isto é o que geralmente se refere ao modo slurp. Isto diz ao operador "read_line" do Perl para ler todo o conteúdo do arquivo e armazenar na variável escalar ao lado esquerdo da atribuição: my $all = &lt;$in>;. Nós usamos inclusive a palavra reservada local quando definimos $/, assim, esta mudança será revertida quando sairmos do bloco - neste caso, uma vez que sairmos da função read_file.

A função write_file é muito mais imediata e nós a colocamos em uma função apenas para fazer o corpo do código similar à solução anterior.

Otras páginas

Perl tutorial

Author

Gabor Szabo (szabgab) Gabor Szabo