Substituir padrão dentro de um arquivo pelo conteúdo de outro arquivo

16

Eu tenho um arquivo de texto ( devel.xml ).

Eu adicionei a palavra REPLACETHIS a ele para substituir essa string pelo conteúdo em um arquivo diferente ( temp.txt ).

A coisa mais próxima que tenho é esta:

sed -i -e "/REPLACETHIS/r temp.TXT" -e "s///" devel.txt;

Isso insere o conteúdo após a string e, em seguida, exclui a string posteriormente.

Esta é a melhor maneira de fazer isso?

    
por RafaelGP 28.09.2012 / 13:07

1 resposta

27

O que você fez foi remover SUBSTITUTETHIS de onde ele aparecer no arquivo (mas não o restante da linha em que aparece) e inserir o conteúdo de temp.TXT abaixo dessa linha. Se SUBSTITUTETHIS aparecer várias vezes em uma linha, somente a primeira ocorrência será removida e somente uma cópia de temp.TXT será adicionada.

Se você quiser substituir a linha inteira quando SUBSTITUTETHIS aparecer, use o comando d . Como você precisa executar os dois r e d quando houver uma correspondência, coloque-os em um grupo reforçado.

sed -e '/SUBSTITUTETHIS/ {' -e 'r temp.TXT' -e 'd' -e '}' -i devel.txt

Algumas implementações de sed permitem usar ponto-e-vírgulas para separar comandos e omitir separadores ao redor de chaves, mas você ainda precisa de uma nova linha para finalizar o argumento para o comando r :

sed -e '/SUBSTITUTETHIS/ {r temp.TXT
                          d}' -i devel.txt

Se você deseja substituir SUBSTITUTETHIS pelo conteúdo do arquivo, mas reter o que vem antes e depois dele na linha, é mais complicado. O método mais simples é incluir o conteúdo do arquivo no comando sed; note que você terá que citar corretamente seu conteúdo.

sed -e "s/SUBSTITUTETHIS/$(<temp.TXT sed -e 's/[\&/]/\&/g' -e 's/$/\n/' | tr -d '\n')/g" -i devel.txt

Ou use o Perl. Isso é curto, mas executa cat uma vez para cada substituição:

perl -pe 's/SUBSTITUTETHIS/'cat temp.TXT'/ge' -i devel.txt

Para ler o arquivo uma vez quando o script iniciar, e evitar depender de um comando shell:

perl -MFile::Slurp -pe 'BEGIN {$r = read_file("temp.TXT"); chomp($r)}
                        s/SUBSTITUTETHIS/$r/ge' -i devel.txt

(apresentado em duas linhas para facilitar a leitura, mas você pode omitir a quebra de linha). Se o nome do arquivo for variável, para evitar problemas de cotação, passe-o para o script por meio de uma variável de ambiente:

replacement_file=temp.TXT perl -MFile::Slurp -pe 'BEGIN {$r = read_file($replacement_file); chomp($r)}
                        s/SUBSTITUTETHIS/$r/ge' -i devel.txt
    
por 29.09.2012 / 02:53