[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
- SED: Inserir linhas entre dois paterns., Rodrigo Tenorio, 2014/10/11
- Re: [shell-script] SED: Inserir linhas entre dois paterns., Paulo Bettega, 2014/10/12
- Re: [shell-script] SED: Inserir linhas entre dois paterns., Ronaldo Ferreira de Lima, 2014/10/12
- Re: [shell-script] SED: Inserir linhas entre dois paterns., Rodrigo Tenorio, 2014/10/12
- Re: [shell-script] SED: Inserir linhas entre dois paterns., Paulo Bettega, 2014/10/12
- Re: [shell-script] SED: Inserir linhas entre dois paterns., Paulo Bettega, 2014/10/12
- Re: [shell-script] SED: Inserir linhas entre dois paterns., itamarnet, 2014/10/13
- Re: [shell-script] SED: Inserir linhas entre dois paterns., Ronaldo Ferreira de Lima, 2014/10/13