Substituir string de múltiplas linhas em arquivos

13

Eu tenho um número de arquivos que eu quero atualizar, substituindo uma seqüência de várias linhas com outra seqüência de várias linhas. Algo ao longo das linhas de:

* Some text, 
* something else
* another thing

E quero substituí-lo por:

* This is completely
* different text

O resultado seria que, após a substituição, o arquivo contendo o primeiro bloco de texto conterá a segunda string (o restante do arquivo permanecerá inalterado).

Parte do problema é que eu tenho que encontrar a lista de arquivos a serem atualizados no sistema de arquivos. Eu acho que posso usar o grep para isso (embora, novamente, não seja tão fácil de fazer com strings de múltiplas linhas), então canalize-o em sed talvez?

Existe uma maneira fácil de fazer isso? Sed é uma opção, mas é estranho, porque eu tenho que adicionar \ n etc. Existe uma maneira de dizer "pegue a entrada desse arquivo, combine-o nesses arquivos e, em seguida, substitua-o pelo conteúdo desse outro arquivo"? Eu posso usar python se necessário, mas eu quero algo rápido e simples, por isso, se houver um utilitário disponível, eu prefiro usar isso do que escrever meu próprio script (o que eu sei fazer).

    
por ventsyv 26.01.2015 / 20:10

4 respostas

9

Substituto "Some ... \ n ... Thing" pelo conteúdo do arquivo "new" em um ou mais arquivos de entrada

perl -i -p0e 's/Some.*?thing\n/'cat new'/se' input.txt ...
  1. -i para alterar o input.txt diretamente
  2. -p0 slurp arquivo de entrada e imprimi-lo no final
  3. s/regexp/.../s na regexp . é .|\n
  4. s/.../exp/e substituir por eval(exp)
  5. novo - um arquivo contendo o texto de substituição (Isso é completamente ... texto diferente)
  6. se for útil, você pode expandir o texto original s/Some text\n...\n...thing\n/...
por 26.01.2015 / 23:12
5
sed -e :n -e '$!N;/\n.*\n/!{$!bn
};  s/some text,\n* *something else\n* *another thing/this is completely\
different text/;P;D' <infile

Eu temo que você tenha dificuldade em encontrar uma solução que lhe agrade até que você descubra uma descrição concreta do problema - mas é para isso que o QA é mais adequado, como eu vejo. Talvez isto lhe dê uma ideia - ele sempre manterá 3 linhas no espaço padrão de cada vez - com uma frente de 2 linhas - enquanto desliza para frente através do arquivo de entrada apenas uma linha por vez.

Ele deve ser capaz de corresponder à sua string, seja ela de várias linhas ou não - até três, ou seja. Mas não há provisões para espelhar essa provisão na substituição - ela sempre abrange duas linhas conforme escritas.

    
por 26.01.2015 / 21:00
1

Outra abordagem sed .

sed '1s/* Some text, 
* something else
* another thing/* This is completely
* different text/' infile.txt 
    
por 22.08.2017 / 06:28
0

Não é strong (porque não chech segunda seqüência, mas é fácil de resolver) e pode ser não é posix compilant mas muito simples:

sed '/^Some text/{:1;/another thing$/!{N;b 1}
     s/.*/this is completely\ndifferent text/g}' input.txt

Primeiro comando adicione linhas de Algum texto até que tenha encontrado outra coisa e depois a segunda linha mude para outro texto.

NOTA A limitação é que Algum texto deve ser sempre seguido por outra coisa .

    
por 26.01.2015 / 22:13