shell-script-pt
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: [shell-script] SED: Inserir linhas entre dois paterns.


From: Ronaldo Ferreira de Lima
Subject: Re: [shell-script] SED: Inserir linhas entre dois paterns.
Date: Sun, 12 Oct 2014 12:01:55 -0300
User-agent: mutt-ng/devel-r804 (Linux)

On Sun, Oct 12, 2014 at 04:26:35AM -0300, Rodrigo Tenorio address@hidden 
[shell-script] wrote:
[...]
> Ok, você está correto. Então suponhamos um possível cenário de erro no arquivo
> original:
> 
> # cat >> testeComErro << EOT
> LINHAS
> LINHAS
> LINHAS
> AAA
> BBB
> LINHAS
> LINHAS
> AAA
> AAA
> EEE
> LINHAS
> LINHAS
> AAA
> EEE
> LINHAS
> LINHAS
> AAA
> CCC
> EOT
> Como evitar que o sed inclua as três linhas entre as duas ocorrências de "AAA"
> e "EEE" encontradas?
Não consegui entender muito bem, é para substituir apenas a primeira
ocorrência e deixar o resto intacto ou é para substituir a primeira e
não imprimir mais nada?

> ...
> Depois de bater cabeça, ler o
> http://unixhelp.ed.ac.uk/CGI/man-cgi?sed
> e
> http://stackoverflow.com/questions/11024245/sed-recipe-how-to-do-stuff-between-two-patterns-that-can-be-either-on-one-line#11048145
> cheguei na solução:
> # sed ':a;/^AAA$/{n;s/^EEE$/BBB\nCCC\nDDD\n&/;Ta;:b;$!{N;bb};q}' testeComErro
> O estranho é que a estrutura geral do arquivo de entrada foi mantida. Mas
> repare a saída com o diff.
> Em teoria, ele só deveria demonstrar a alteração entre o primeiro "AAA" 
> seguido
> de "EEE". 
O comando  'q' é  usado somente na  última linha, quando  já não  é mais
necessário. O código ':b;$!{N;bb}' garante  que o looping seja executado
até a  penúltima linha, qualquer comando  que você coloque após  só será
executado quando chegar na última linha  do arquivo. Fazendo um teste de
conceito simples,  adicione, por  exemplo, um  's/$/\nexecuntado comando
"q"/' entre o código citado e o comando 'q', depois executei sem o bloco
em questão.

> No entanto:
> 
> # diff -y teste <(sed
> ':a;/^AAA$/{n;s/^EEE$/BBB\nCCC\nDDD\n&/;Ta;:b;$!{N;bb};q}' testeComErro)
> 
> Dessa vez eu fiquei sem saber se eu acertei ou errei...
1. Se o caso for para modificar a primeira ocorrência e interromper a
   impressão, você pode tentar:

    $ sed 'ba;:b;q;:a;/^AAA$/{n;s/^EEE$/BBB\nCCC\nDDD\n&/;tb;}' testeComErro 

  'tb' => quando encontrar a primeira ocorrência pule para o label ':b' e
          interrompa a execução (comando 'q').

2. Se o caso for para modificar a primeira ocorrência e deixar o resto
do arquivo intacto (agora a coisa começa a ficar divertida de verdade):

    1 {
        x;
        s/.*/NAO/;
        x;
    };
    
    :a;
    /^AAA$/ {
        x;/SIM/{x;bb;};x;
        n;
        s/^EEE$/BBB\nCCC\nDDD\n&/;
        Ta;
        x;s/NAO/SIM/;x;
    }
    :b

nesse exemplo, estamos  utilizando o hold space para  armazenar o estado
da substituição que,  no início é 'NAO' (de não  modificado) para testar
em todas as ocorrências se a substituição já foi feita ('SIM').

[]'s
-- 
"Não manejo bem as palavras
Mas manipulo bem as strings."
------------------------------
http://tecnoveneno.blogspot.com


reply via email to

[Prev in Thread] Current Thread [Next in Thread]