Multi-line replace

7

Eu passei eras tentando descobrir isso. Acontece que não preciso mais fazê-lo; Eu encontrei outro caminho. Mas, pelo bem da minha sanidade, gostaria de saber a resposta de qualquer maneira.

É muito fácil usar sed para substituir um marcador por algum texto. O que não consigo descobrir é como fazer com que sed insira um enorme bloco de texto, com formatações complexas, como várias linhas, caracteres de tabulação, etc. Como você faz isso? O sed é a melhor coisa a usar ou o quê?

    
por MathematicalOrchid 26.02.2013 / 00:10

5 respostas

3

Se você tiver o texto a ser inserido no (s) marcador (es) em um arquivo chamado /tmp/insert.txt, você pode realizar essa tarefa da seguinte forma:

sed '/MARKER/ r /tmp/insert.txt' < inputfile

O comando acima sed irá ler "inputfile" e procurar por MARKER. Quando o encontrar, ele insere o conteúdo de /tmp/insert.txt no fluxo de saída.

Se você quiser que o marcador seja excluído, tente o seguinte:

sed '/MARKER/ {s/MARKER//; r /tmp/insert.txt
}' <inputfile

Observe que a chave de fechamento "}" deve ser precedida por uma nova linha.

Como no primeiro comando, o sed irá operar em linhas com o MARKER. Ele irá substituir o MARKER por nada, e então ele irá ler em /tmp/insert.txt

    
por 26.02.2013 / 15:15
3

Eu usaria ex para esse tipo de tarefa, a menos que você realmente tenha um fluxo de dados. Eu manteria os comandos ex em um documento aqui:

ex $FILENAME << END_EX_COMMANDS
" Find the mark, assuming it's an entire line
/^MARKER$/
" Delete the marker line
d
" Add the complex, multi-line text
a
Complex, vividly formatted text here.
Even more "specially" formatted text.
.
" The '.' terminates the a-command. Write out changed file.
w!
q
END_EX_COMMANDS

Usar ex é uma vantagem para vi ou vim usuários: eles já conhecem as teclas para os comandos, embora isso lhe dê a sensação de editar cegos. Você também pode fazer várias adições ou substituições globais, qualquer coisa que vim possa fazer no modo ':'.

    
por 26.02.2013 / 14:36
1

Eu acredito que este comando é o que você está procurando:

r FILENAME
     As a GNU extension, this command accepts two addresses.

     Queue the contents of FILENAME to be read and inserted into the
     output stream at the end of the current cycle, or when the next
     input line is read.  Note that if FILENAME cannot be read, it is
     treated as if it were an empty file, without any error indication.

     As a GNU 'sed' extension, the special value '/dev/stdin' is
     supported for the file name, which reads the contents of the
     standard input.
    
por 26.02.2013 / 01:07
0

Aqui está uma versão simplificada da resposta de Bruce Ediger usando comando de mudança que é uma combinação de delete e append.

ex $FILENAME << EOEX
/^MARKER$/c
The new text
to be inserted
here.
.
w!
q
EOEX
    
por 16.08.2016 / 13:25
0

Se você quiser que o marcador seja excluído, tente isso em uma linha:

sed -e '/MARKER/ r /tmp/insert.txt' -e '/MARKER/d' < inputfile

ou

sed -e '/MARKER/ {r /tmp/insert.txt' -e 'd }' < inputfile
    
por 20.09.2016 / 16:07

Tags