Como substituo várias linhas por uma única palavra no arquivo (inplace replace)?

7

O conteúdo do meu arquivo filename é o seguinte (por exemplo):

My block of line starts from here 
START
First line
second line
third line
END
and end to here for example.

Eu quero substituir o bloco de linhas entre START e END com apenas uma palavra, por exemplo, com SINGLEWORD . Como abaixo:

My block of line starts from here 
SINGLEWORD
and end to here for example.

Eu posso encontrar meu bloco de linhas usando este comando:

grep -Pzo "START(.|\n)*END" filename

E o resultado da execução do comando acima será assim:

START
First line
second line
third line
END

Então usei este comando para combinar todas as linhas em uma única linha:

LAST_RESULT | sed -e :a -e '/$/N; s/\n/ /; ta'

Depois, obtenho este resultado:

START First line second line third line END

E com o meu último comando LAST_RESULTS | sed 's/.*/SINGLEWORD/' , mudo-os para "SINGLEWORD" e obtenho este resultado.

SINGLEWORD

Agora, o que eu quero é: Como posso usar este comando (ou seu comando de sugestão) e substituir (no lugar) o meu bloco de linhas para a palavra "SINGLEWORD"? E o resultado final será como este arquivo:

My block of line starts from here 
SINGLEWORD
and end to here for example.
    
por αғsнιη 07.10.2014 / 16:00

2 respostas

9

Isso pode ser feito facilmente em perl :

$ perl -i -p0e 's/START.*?END/SINGLEWORD/s' file
$ cat file
My block of line starts from here 
SINGLEWORD
and end to here for example. 

Explicação

-0 define o separador de linha como nulo

-p aplica o script fornecido por -e a cada linha e imprime essa linha

O modificador regexp:

  • /s Trate a string como uma única linha. Ou seja, altere . para corresponder a qualquer caractere, mesmo uma nova linha, que normalmente não seria compatível.

Por que o ? :

  • Por padrão, um subpadrão quantificado é "ganancioso", ou seja, ele corresponderá quantas vezes for possível (considerando um local inicial específico) enquanto ainda permite que o restante do padrão corresponda. Se você quiser que ele corresponda ao número mínimo de vezes possível, siga o quantificador com ? .
por Sylvain Pineau 07.10.2014 / 17:59
10

Eu queria saber se isso é possível sem perl , python e outros. E eu encontrei esta solução usando sed :

$ sed ':a;N;$!ba;s/START.*END/SINGLEWORD/g' filename

Explicação:

  1. : a cria um marcador 'a'
  2. N acrescenta a próxima linha ao espaço padrão
  3. $! se não for a última linha , ba ramificação (vá para) label 'a'
  4. s substituto , /START.*END/ por SINGLEWORD , / g correspondência global (quantas vezes puder)

Foi encontrado aqui .

@KasiyA, obrigado eu aprendi muitas coisas interessantes!

    
por c0rp 07.10.2014 / 19:40