[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: |
Sat, 11 Oct 2014 23:23:48 -0300 |
User-agent: |
mutt-ng/devel-r804 (Linux) |
Saudações Rodrigo,
On Sat, Oct 11, 2014 at 09:46:44PM -0300, Rodrigo Tenorio address@hidden
[shell-script] wrote:
[...]
> Tenho o seguinte cenário:
>
> cat >> teste << EOT
> LINHAS
> LINHAS
> AAA
> BBB
> LINHAS
> AAA
> EEE
> LINHAS
> LINHAS
> LINHAS
> EOT
>
> Preciso inserir as linhas BBB, CCC, DDD somente quando a próxima linha de AAA
> for EEE.
> Eu consegui localizar e imprimir com:
>
> # sed -n "/^AAA/g;{n;/^EEE/p}" teste
Há erros semânticos nesse sed-1liner:
1. '/^AAA/g' => procure por tudo o que começa com "AAA" e não faça
nada além disto.
2. '{n;' => para cada linha, descarte a atual e coloque a próxima
no pattern space.
2.1. '/^EEE/p}' => se a linha começar com "EEE", imprima.
Aplicando esse comando no exemplo acima, o resultado esperado não é
reproduzido porque o 1liner imprime "EEE" apenas se ele estiver em
linhas pares. Experimente exatamente o mesmo código com o seguinte
exemplo:
1
EEE
3
EEE
5
EEE
7
e você terá três "EEE" como saída.
> Mas ao trocar o "p" para "i BBB" recebo o seguinde retorno:
>
> # sed -n "/^AAA/g;{n;/^EEE/i BBB}" teste
> sed: -e expressão #1, caractere 0: `{' não terminada
> Acreditava que se eu conseguia imprimir o EEE, eu conseguiria adicionar
> conteúdo antes dele.
Aqui além do problema semântico, há problemas de sintaxe,
precisaria ser reescrito para que o comando "i" fique entre colchetes
(indicando um bloco de comando operando para um endereço), para manter o
1liner, ainda seria necessário utilizar dois '-e'.
> ...
> Bem. Depois de muito bater cabeça, cheguei no ponto em que o sed fez o que eu
> precisava...
>
> # sed -r ":a;/^AAA/{n;/^EEE/bc};n;ba;:c;i BBB" teste
>
> ... Mas ainda faltam inserir as linhas CCC e DDD. E isso eu consegui usando "i
> BBB \nCCC \nDDD".
>
> Destrinchando a coisa da maneira que entendi:
> :a # marcador e início de fluxo de ER.
> /^AAA/ # pesquisa pelo patern AAA que começa com um A, devido ao ^.
> {
> n # pula para a próxima linha.
> /^EEE/ # similar ao /^AAA/.
> bc # salto para o fluxo de ER "c": o "b" é o salto e o "c" é o endereço para
> onde ele vai saltar.
> }
> n # pula para a próxima linha.
> ba # similar ao "bc".
> :c # similar ao ":a".
> i BBB # o "i" insere cadeias de caracteres, na linha imediatamente anterior à
> linha corrente; no caso "BBB".
> É isso.
Esta parte está ok, apenas muito complexa.
> Se eu tiver entendido a coisa errado, se houver ideias complementares; ou se
> houver uma forma melhor de fazer isso, por favor sintam-se livres para
> responder.
Você pode resumir para:
$ sed '/^AAA$/{n;s/^EEE$/BBB\nCCC\nDDD\n&/}' teste
Para facilitar a visualização do resultado final para este caso, pode-se
usar, por exemplo, um diff -y:
$ diff -y teste <(sed '/^AAA$/{n;s/^EEE$/BBB\nCCC\nDDD\n&/}' teste)
ou ainda trocar o 'diff -y' por 'vimdiff'.
> Grande abraço,
> Rodrigo Boechat
[]'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.,
Ronaldo Ferreira de Lima <=
- Re: [shell-script] SED: Inserir linhas entre dois paterns., Rodrigo Tenorio, 2014/10/11
- 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., Ronaldo Ferreira de Lima, 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., Ronaldo Ferreira de Lima, 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., Ronaldo Ferreira de Lima, 2014/10/12
- Re: [shell-script] SED: Inserir linhas entre dois paterns., Rodrigo Tenorio, 2014/10/12