Carregando ...
Desculpe, ocorreu um erro ao carregar o conteúdo.
 

2 aspas, sem PCRE

Expandir mensagens
  • Luciano ES
    Boas tardes a todos, No último fim de semana, entreti-me com este desafio, pena que o desafio levou a melhor... :-) INTRODUÇÃO: Tenho um dump de um banco
    Mensagem 1 de 9 , 29 de abr de 2003
      Boas tardes a todos,
      No último fim de semana, entreti-me com este desafio, pena que o desafio
      levou a melhor... :-)

      INTRODUÇÃO:

      Tenho um dump de um banco de dados SQlite. O SQlite tem a seguinte
      característica: os campos são delimitados por aspas simples. Se o
      próprio valor da célula tiver aspa simples, é preciso neutralizá-la
      (escapar) com outra aspa simples. Aspa simples e 'nulo' são os únicos
      caractere que precisam ser "escapados" no SQlite. Vejamos um trecho de
      exemplo:

      campos: número, inglês, português, documento, observação.

      INSERT INTO huge VALUES(2,'(cash) dividends','dividendos','Mini Bal
      DN','Uma das bobagens registradas nos nossos dicionários bilíngües
      é o tal do dividendos em dinheiro. Isso não existe. Dividendo é, por
      definição, em dinheiro. --> Bonificação.');
      INSERT INTO huge VALUES(194,'architect''s certificate','declaração de
      serviços prestados','Jur','null');
      INSERT INTO huge VALUES(3,'(debenture) premium','prêmio (sobre emissão
      de debêntures)','Mini Bal DN','Este prêmio é o excesso do valor pelo
      qual uma debênture é emitida sobre seu valor nominal.');
      INSERT INTO huge VALUES(4,'(e)','alínea "e"','Jur','null');
      INSERT INTO huge VALUES(5,'(shareholders, stockholders)
      equity.','patrimônio líquido','Mini Bal DN','null');

      Note, no segundo registro, o uso da aspa simples: a palavra é
      "architect's certificate", mas é preciso escrevê-la como architect''s
      certificate, para neutralizar a aspa simples.


      OBJETIVO:

      Capturar o conteúdo de cada coluna do banco de dados, para converter
      tudo em outro formato. Digamos, XML.

      Então, tentei o seguinte:

      localiza:
      INSERT INTO [^ ]+ VALUES *\( *(')?((?:[^']|'')+)\1? *,
      *(')?((?:[^']|'')+)\3? *, *(')?((?:[^']|'')+)\5? *, *(')?((?:[^']|'')+)\7?
      *, *(')?((?:[^']|'')+)\9? *\);

      e substitui por:
      \t<termo>\n\t\t<number>\2</number>\n\t\t<English>\4</English>\n\t\t<Portugue
      se>\6</Portuguese>\n\t\t<Glossary>\8</Glossary>\n\t\t<Comentario>\10</Coment
      ario>


      EXPLICAÇÃO:
      *(')?((?:[^']|'')+)\1? *,
      um ou mais espaços opcionais e uma aspa simples opcional. Se tiver a
      aspa, captura a danada no grupo para verificar se tem outra - \1 - no fim
      da seqüência. Ou seja, se o primeiro caractere não for uma aspa mas o
      último for, nem esquenta com essa última porque tem que ter aspas dos
      dois lados, então a última não tem nada a ver. A aspa tem que ser
      opcional porque se o campo contiver apenas um número, ele pode vir sem
      aspas. Daí vem um número indefinido de qualquer coisa que não seja
      aspa simples, OU duas aspas simples em seqüência. "Ou duas aspas
      simples em seqüência" serve para eu capturar o "architect''s
      certificate" do segundo registro, por exemplo. Encerrando, case uma aspa
      simples com \1, mas só se ela já tiver sido casada no começo. E
      permita vários espaços adicionais antes da vírgula.


      PROBLEMA 1:
      Muitos grupos. No finzinho, estico o braaa-aaaa-aaa-ço para apanhar o
      grupo 10 (aaaah!)... mas sed não faz isso. Então, parece que sed não
      serve para esta tarefa. Principalmente porque outros bancos de dados podem
      ter mais que 5 colunas, vai ferrar com tudo. Mas este problema é quase
      off-topic. Vamos ao segundo, que é o que interessa.

      PROBLEMA 2:
      O que realmente interessa: note que eu usei PCRE. Mais especificamente,
      usei grupos "fantasma" (?:), para reduzir o número de grupos e tentar me
      manter dentro do limite de 9 retrovisores, mas não colou. E, como eu já
      disse, bancos de dados podem ter mais que 5 colunas, vai ferrar com tudo,
      então não dá mesmo. Mas daí eu pensei:
      seria possível escrever *(')?((?:[^']|'')+)\1? *, gastando apenas 2
      grupos, e sem usar PCRE?

      E foi aí que a fêmea do suíno flexionou o apêndice caudal.

      Pergunta especialmente dedicada ao brontossauro Aurélio, que despreza
      PCRE com toda aquela desfaçatez que lhe é característica. :-)))

      --
      Luciano Espirito Santo
      Santos, SP - Brasil
    • Thobias Salazar Trevisan
      ae luciano, ... eu usaria uma outra abordagem para fazer isto. O que separa campos é , , aspas virgula aspas. Então eu substituiria isto por algum
      Mensagem 2 de 9 , 30 de abr de 2003
        ae luciano,

        On Tue, 29 Apr 2003, Luciano ES wrote:

        > campos: número, inglês, português, documento, observação.
        >
        > INSERT INTO huge VALUES(2,'(cash) dividends','dividendos','Mini Bal
        > DN','Uma das bobagens registradas nos nossos dicionários bilíngües
        > é o tal do dividendos em dinheiro. Isso não existe. Dividendo é, por
        > definição, em dinheiro. --> Bonificação.');
        > INSERT INTO huge VALUES(194,'architect''s certificate','declaração de
        > serviços prestados','Jur','null');
        > INSERT INTO huge VALUES(3,'(debenture) premium','prêmio (sobre emissão
        > de debêntures)','Mini Bal DN','Este prêmio é o excesso do valor pelo
        > qual uma debênture é emitida sobre seu valor nominal.');
        > INSERT INTO huge VALUES(4,'(e)','alínea "e"','Jur','null');
        > INSERT INTO huge VALUES(5,'(shareholders, stockholders)
        > equity.','patrimônio líquido','Mini Bal DN','null');
        >
        > Note, no segundo registro, o uso da aspa simples: a palavra é
        > "architect's certificate", mas é preciso escrevê-la como architect''s
        > certificate, para neutralizar a aspa simples.
        >
        > OBJETIVO:
        > Capturar o conteúdo de cada coluna do banco de dados, para converter
        > tudo em outro formato. Digamos, XML.
        >
        > e substitui por:
        > \t<termo>\n\t\t<number>\2</number>\n\t\t<English>\4</English>\n\t\t<Portugue
        > se>\6</Portuguese>\n\t\t<Glossary>\8</Glossary>\n\t\t<Comentario>\10</Coment
        > ario>
        > PROBLEMA 2:
        > seria possível escrever *(')?((?:[^']|'')+)\1? *, gastando apenas 2
        > grupos, e sem usar PCRE?

        eu usaria uma outra abordagem para fazer isto. O que separa
        campos é "','", aspas virgula aspas. Então eu substituiria isto
        por algum caracter maluco e usaria como delimitador. olhe:

        #!/bin/sed -nf

        /INSERT INTO huge VALUES(/{
        :a
        /);/!{
        N
        s/\n//g
        ta
        }
        # ate aqui foi pra colocar cada insert na mesma linha
        s/','/§/g # substituimos por outro caracter
        # colocamos a linha no reserva
        h

        # aqui fizemos o tratamento para um campo, pegamos do reserva,
        # fizemos para outro campo, pegamos do reserva....
        s/INSERT INTO huge VALUES(\([0-9]\+\),\(.*\)/\
        <termo>\
        <number>\1<\/number>/p
        g
        s/INSERT INTO huge VALUES([0-9]\+,'\([^§]*\)§.*/<English>\1<\/English>/p
        g
        s/^[^§]\+§\([^§]\+\)§.*/<Portugue>\1<\/Portuguese>/p
        g
        s/^[^§]\+§[^§]\+§\([^§]\+\)§.*/<Glossary>\1<\/Glossary>/p
        g
        s/^[^§]\+§[^§]\+§[^§]\+§\([^§]\+\)');/<Comentario>\1<\/Comentario>\
        <\/termo>/p
        }

        note que usando vários 's' pra pegar os campos você deixa o
        código mais limpo e não tem o limite dos 9 retrovisores.
        assim, pode ter quantos campos quiser, basta adicional no final
        mais um tratamento pra ele.

        $ ./script.sed < sql

        <termo>
        <number>2</number>
        <English>(cash) dividends</English>
        <Portugue>dividendos</Portuguese>
        <Glossary>Mini BalDN</Glossary>
        <Comentario>Uma das bobagens registradas nos nossos dicionários
        bilíngüesé o tal do dividendos em dinheiro. Isso não existe. Dividendo
        é, pordefinição, em dinheiro. --> Bonificação.</Comentario>
        </termo>

        <termo>
        <number>194</number>
        <English>architect''s certificate</English>
        <Portugue>declaração deserviços prestados</Portuguese>
        <Glossary>Jur</Glossary>
        <Comentario>null</Comentario>
        </termo>
        .....

        Sobre as suas dúvidas deixo pro aurelio (nao manjo muito de PCRE)

        falow

        thobias
        -------
        echo 9446046325380026818553633794429812592304650P | dc
        -------
        http://www.lcp.coppe.ufrj.br/~thobias

        ____________________________
        |
        | Against - HTML Mail
        | Against - MS ATTACHMENTS
        |
        ----------------------------
      • Luciano ES
        Caramba, Thobias, você viaja mais que o Aurélio, tá difícil entender tudo que tu fez aqui. Achei interessante a idéia de trocar aspa-vírgula-aspa por
        Mensagem 3 de 9 , 30 de abr de 2003
          Caramba, Thobias, você viaja mais que o Aurélio, tá difícil
          entender tudo que tu fez aqui.

          Achei interessante a idéia de trocar aspa-vírgula-aspa por outro
          delimitador. Por um momento, achei mesmo que você tinha colocado o ovo em
          pé. Mas tem uns problemas, fora um monte de coisa que eu não estou
          entendendo. Vamos ver apenas uma ou duas:

          - trocar aspa-vírgula-aspa por outro delimitador não deveria
          funcionar. Funciona, mas não deveria. Note que se um campo contiver
          apenas número, ele vem sem aspas. Baseando-se no critério
          "aspa-vírgula-aspa", acho que você está calculando errado o número
          de campos. Eu copiei e rodei o seu script (que, aliás, está muito
          complicado para o meu bestunto). Olha só o que ele fez:
          -------------------------------- 8< --------------------------------
          <termo>
          <number>194</number>
          <English>architect''s certificate</English>
          <Portugue>declaração de serviços prestados</Portuguese>
          <Glossary>Jur</Glossary>
          <Comentario>null</Comentario>
          </termo>
          <Comentario>null</Comentario>
          </termo>
          -------------------------------- >8 --------------------------------

          O campo <Comentario> aparece repetido. Será que isso não é efeito
          colateral do critério "aspa-vírgula-aspa"? Eu estou debugando seu
          script, mas tá nublado o céu aqui. Acho que está na hora de eu
          aprender a usar o sedsed...


          >#!/bin/sed -nf
          >
          >/INSERT INTO huge VALUES(/{
          > :a
          > /);/!{
          > N
          > s/\n//g
          > ta
          > }
          ># ate aqui foi pra colocar cada insert na mesma linha


          - - Não entendi nada dessa parte. Se eu executar o script só até
          essa parte, não acontece nada. Nada muda. O que você quer dizer com
          "colocar cada insert na mesma linha"?

          Por enquanto, só isso. Aos poucos, aos poucos...

          --
          Luciano Espirito Santo
          Santos, SP - Brasil


          <-quote-> **************************************************
          On 30/04/03 at 09:08, Thobias Salazar Trevisan wrote in 4K:
          Assunto/Subject: Re: [sed-br] 2 aspas, sem PCRE

          >ae luciano,
          >
          >eu usaria uma outra abordagem para fazer isto. O que separa
          >campos é "','", aspas virgula aspas. Então eu substituiria isto
          >por algum caracter maluco e usaria como delimitador. olhe:
          >
          >#!/bin/sed -nf
          >
          >/INSERT INTO huge VALUES(/{
          > :a
          > /);/!{
          > N
          > s/\n//g
          > ta
          > }
          ># ate aqui foi pra colocar cada insert na mesma linha
          > s/','/§/g # substituimos por outro caracter
          ># colocamos a linha no reserva
          > h
          >
          ># aqui fizemos o tratamento para um campo, pegamos do reserva,
          ># fizemos para outro campo, pegamos do reserva....
          > s/INSERT INTO huge VALUES(\([0-9]\+\),\(.*\)/\
          ><termo>\
          ><number>\1<\/number>/p
          > g
          > s/INSERT INTO huge
          VALUES([0-9]\+,'\([^§]*\)§.*/<English>\1<\/English>/p
          > g
          > s/^[^§]\+§\([^§]\+\)§.*/<Portugue>\1<\/Portuguese>/p
          > g
          > s/^[^§]\+§[^§]\+§\([^§]\+\)§.*/<Glossary>\1<\/Glossary>/p
          > g
          >
          s/^[^§]\+§[^§]\+§[^§]\+§\([^§]\+\)');/<Comentario>\1<\/Comenta
          rio>\
          ><\/termo>/p
          >}
          >
          >note que usando vários 's' pra pegar os campos você deixa o
          >código mais limpo e não tem o limite dos 9 retrovisores.
          >assim, pode ter quantos campos quiser, basta adicional no final
          >mais um tratamento pra ele.
          >
          >$ ./script.sed < sql
          >

          ********* END OF ORIGINAL MESSAGE *********</-quote->
        • Thobias Salazar Trevisan
          ae luciano, ... ah! ok. no script abaixo está arrumado.... ... hmm, não era pra ter este problema. no script abaixo ta arrumado ... O que estou fazendo aqui
          Mensagem 4 de 9 , 2 de mai de 2003
            ae luciano,

            On Wed, 30 Apr 2003, Luciano ES wrote:

            > - trocar aspa-vírgula-aspa por outro delimitador não deveria
            > funcionar. Funciona, mas não deveria. Note que se um campo contiver
            > apenas número, ele vem sem aspas. Baseando-se no critério
            > "aspa-vírgula-aspa", acho que você está calculando errado o número
            > de campos.

            ah! ok. no script abaixo está arrumado....

            > Eu copiei e rodei o seu script (que, aliás, está muito
            > complicado para o meu bestunto). Olha só o que ele fez:
            > -------------------------------- 8< --------------------------------
            > <termo>
            > <number>194</number>
            > <English>architect''s certificate</English>
            > <Portugue>declaração de serviços prestados</Portuguese>
            > <Glossary>Jur</Glossary>
            > <Comentario>null</Comentario>
            > </termo>
            > <Comentario>null</Comentario>
            > </termo>
            > -------------------------------- >8 --------------------------------
            > O campo <Comentario> aparece repetido. Será que isso não é efeito
            > colateral do critério "aspa-vírgula-aspa"?

            hmm, não era pra ter este problema. no script abaixo ta arrumado

            > >#!/bin/sed -nf
            > >
            > >/INSERT INTO huge VALUES(/{
            > > :a
            > > /);/!{
            > > N
            > > s/\n//g
            > > ta
            > > }
            > ># ate aqui foi pra colocar cada insert na mesma linha
            > - - Não entendi nada dessa parte. Se eu executar o script só até
            > essa parte, não acontece nada. Nada muda. O que você quer dizer com
            > "colocar cada insert na mesma linha"?

            O que estou fazendo aqui é apenas colocar cada insert em uma
            única linha. como no mail que você mandou algumas pareciam estar
            em 2 ou 3 linhas..... se um insert estiver assim:

            INSERT INTO huge VALUES(194,'architect''s certificate','declaração de
            serviços prestados','Jur','null');

            em 2 linhas, ele vai deixá-lo em uma única linha.

            INSERT INTO huge VALUES(194,'architect''s certificate','declaração de serviços prestados','Jur','null');

            Bom, aqui está o script arrumado. vamos às explicações.

            #!/bin/sed -nf

            /INSERT INTO huge VALUES(/{
            :a
            /);/!{
            N
            s/\n//g
            ta
            }
            # aqui temos cada INSERT em uma única linha, ou seja,
            # INSERT .........
            # INSERT .........
            # ....
            s/','/§/g
            # trocamos ',' por §
            s/\([0-9]\+\),'\?/\1§/
            # trocamos números seguidos de , com ' opcional pelo número§
            # guardamos esta nova linha no reserva. ex:
            # INSERT INTO huge VALUES(5§(shareholders, stockholders)equity.§
            # patrimônio líquido§Mini Bal DN§null');
            # todo o insert estava na mesma linha, quebrei pro mail ficar melhor!!!
            h
            # agora comecamos a fazer o cut dos campos que queremos.
            # primeiro, deixamos soh o número do ítem.
            s/^[^§]\+(\([0-9]\+\)§.*/\
            <termo>\
            <number>\1<\/number>/p
            # voltamos a linha original com os § e fizemos o proximo cut....
            g
            s/^[^§]\+§\([^§]*\)§.*/<English>\1<\/English>/p
            # voltamos a linha original....
            g
            s/^[^§]\+§[^§]\+§\([^§]\+\)§.*/<Portugue>\1<\/Portuguese>/p
            g
            s/^[^§]\+§[^§]\+§[^§]\+§\([^§]\+\)§.*/<Glossary>\1<\/Glossary>/p
            g
            s/^[^§]\+§[^§]\+§[^§]\+§[^§]\+§\([^§]\+\)');/<Comentario>\1<\/Comentario>\
            <\/termo>/p
            }

            $ script.sed sql

            <termo>
            <number>2</number>
            <English>(cash) dividends</English>
            <Portugue>dividendos</Portuguese>
            <Glossary>Mini BalDN</Glossary>
            <Comentario>Uma das bobagens registradas nos nossos dicionários
            bilíngüesé o tal do dividendos em dinheiro. Isso não existe. Dividendo
            é, pordefinição, em dinheiro. --> Bonificação.</Comentario>
            </termo>

            <termo>
            <number>194</number>
            <English>architect''s certificate</English>
            <Portugue>declaração deserviços prestados</Portuguese>
            <Glossary>Jur</Glossary>
            <Comentario>null</Comentario>
            </termo>

            <termo>
            <number>3</number>
            <English>(debenture) premium</English>
            <Portugue>prêmio (sobre emissãode debêntures)</Portuguese>
            <Glossary>Mini Bal DN</Glossary>
            <Comentario>Este prêmio é o excesso do valor peloqual uma debênture é
            emitida sobre seu valor nominal.</Comentario>
            </termo>
            ....

            bom, aqui não ficou repetido, se tiver algum problema mande a
            versão do sed que você está usando.

            falow

            thobias
            -------
            echo 9446046325380026818553633794429812592304650P | dc
            -------
            http://www.lcp.coppe.ufrj.br/~thobias

            ____________________________
            |
            | Against - HTML Mail
            | Against - MS ATTACHMENTS
            |
            ----------------------------
          • aurelio
            ae luciano, finalmente vou limpar o INBOX... espero que ainda te sirva. AVISO: e-mail looooongo e chato, leia quando estiver com tempo. ... beleza, muito bom
            Mensagem 5 de 9 , 8 de mai de 2003
              ae luciano,

              finalmente vou limpar o INBOX... espero que ainda te sirva.

              AVISO: e-mail looooongo e chato, leia quando estiver com tempo.

              --- Luciano ES <luc-groups@...> escreveu:
              > Tenho um dump de um banco de dados SQlite. O SQlite tem a seguinte
              > característica: os campos são delimitados por aspas simples.
              > Se o próprio valor da célula tiver aspa simples, é preciso
              > neutralizá-la (escapar) com outra aspa simples.

              beleza, muito bom ter uma idéia do negócio antes de saber o
              problema, valeu.

              [exemplo]
              > INSERT INTO huge VALUES(2,'(cash) dividends','dividendos','Mini Bal
              > DN','Uma das bobagens registradas nos nossos dicionários bilíngües
              > é o tal do dividendos em dinheiro. Isso não existe. Dividendo é, por
              > definição, em dinheiro. --> Bonificação.');

              >OBJETIVO:
              > Capturar o conteúdo de cada coluna do banco de dados, para
              > converter tudo em outro formato. Digamos, XML.

              ok.

              > Então, tentei o seguinte:
              > INSERT INTO [^ ]+ VALUES *\( *(')?((?:[^']|'')+)\1? *,
              > *(')?((?:[^']|'')+)\3? *, *(')?((?:[^']|'')+)\5? *,
              > *(')?((?:[^']|'')+)\7?
              > *, *(')?((?:[^']|'')+)\9? *\);

              não, não, não :)
              você está tentando fazer uma escultura de um tronco de árvore
              sujo, com casca e musgo. primeiro você tem que limpar a madeira,
              descascá-la, e só começar a escultura quando ela estiver limpa
              e pronta para ser manipulada.

              no teu caso, isso significa primeiro antes de começar a brincar,
              tirar o lixo como:

              1 - apagar 'INSERT INTO bla VALUES (' do começo
              2 - apagar ');' do final
              3 - proteger as aspas escapadas ''

              pra começar tá bom, depois tem mais. eu reduzi um pouco teus
              exemplos pra caber na tela:

              # cat lixo
              INSERT INTO h VALUES(2,'(c) div','dividendos','MBalDN','Uma das ...');
              INSERT INTO h VALUES(194,'arch''s cert','dec serv prest','Jur','null');
              INSERT INTO h VALUES(3,'(deb) prem','prêmio (deb)','MBalDN','Este
              ...');
              INSERT INTO h VALUES(4,'(e)','alínea "e"','Jur','null');
              INSERT INTO h VALUES(5,'(srhol, stkhol)>eq.','patlíq','MBalDN','null');

              # cat lixo | sed "s/^[^(]*(// ; s/);$// ; s/''/@@@/g"
              2,'(c) div','dividendos','MBalDN','Uma das ...'
              194,'arch@@@s cert','dec serv prest','Jur','null'
              3,'(deb) prem','prêmio (deb)','MBalDN','Este ...'
              4,'(e)','alínea "e"','Jur','null'
              5,'(srhol, stkhol)>eq.','patlíq','MBalDN','null'

              então agora os 3 primeiros passos da limpeza estão feitos.
              agora falta o principal: normalizar os delimitadores.

              como temos vários delimitadores: vírgula, aspas+vírgula+aspas
              aspas+vírgula e vírgula+aspas, precisamos trocar todas essas
              possibilidades por um delimitador único, assim como o thobias
              fez.

              primeiro, qual a ER que casa todas essas possibilidades de
              delimitadores? um simples '?,'? serve, ou seja,
              uma vírgula com aspas opcionais antes e depois.

              # echo "1,2,'a',3,'b','c'" | sed "s/'\?,'\?/./g"
              1.2.a.3.b.c'

              a aspas de final se tira com mais um s///, isso não é problema.
              mas e se tiver vírgulas dentro do texto entre aspas?

              # echo "1,2,'a,a',3,'b,b','c,c'" | sed "s/'\?,'\?/./g"
              1.2.a.a.3.b.b.c.c' <------ ERRADO

              opa! então precisamos proteger mais um caractere, para que ele
              não interfira na nossa ER, vamos trocar todas as vírgulas que
              estão *dentro das aspas* por digamos %%%.

              # echo "1,2,'a,a',3,'b,b','c,c'" |
              sed "s/\('[^']\+\),\([^']*'\)/\1%%%\2/g"
              1,2,'a%%%a',3,'b%%%b','c%%%c'

              beleza! agora podemos juntar a ER '?,'? anterior pra unificar
              os delimitadores de campo, e já converter para a cobrinha §:

              # echo "1,2,'a,a',3,'b,b','c,c'" |
              sed "s/\('[^']\+\),\([^']*'\)/\1%%%\2/g ; s/'\?,'\?/§/g"
              1§2§a%%%a§3§b%%%b§c%%%c'

              beleza! agora falta voltar as vírgulas ao normal e tirar aquela]
              aspinha do final que sobrou:

              # echo "1,2,'a,a',3,'b,b','c,c'" |
              sed "s/\('[^']\+\),\([^']*'\)/\1%%%\2/g ; s/'\?,'\?/§/g
              s/%%%/,/g ; s/'$//"
              1§2§a,a§3§b,b§c,c

              maaaaaaaassa.

              então até já podemos gravar o limpa.sed:

              --------------------------------------------------
              # limpa.sed

              # apaga o 'INSERT INTO bla VALUES (' do começo
              s/^[^(]*(//
              # apaga o ');' do final
              s/);$//
              # protege as aspas escapadas
              s/''/@@@/g
              # protege as virgulas dentro das aspas
              s/\('[^']\+\),\([^']*'\)/\1%%%\2/g
              # usa a cobrinha § como unico delimitador de campos
              s/'\?,'\?/§/g
              # restaura as virgulas
              s/%%%/,/g
              # restaura as aspas escapadas
              s/@@@/'/g
              # troca aspinha-lixo do final por um delimitador
              s/'$/§/
              --------------------------------------------------

              testando:

              # cat lixo
              INSERT INTO h VALUES(2,'(c) div','dividendos','MBalDN','Uma das ...');
              INSERT INTO h VALUES(194,'arch''s cert','dec serv prest','Jur','null');
              INSERT INTO h VALUES(3,'(deb) prem','prêmio (deb)','MBalDN','Este
              ...');
              INSERT INTO h VALUES(4,'(e)','alínea "e"','Jur','null');
              INSERT INTO h VALUES(5,'(srhol, stkhol)>eq.','patlíq','MBalDN','null');

              # cat lixo | sed -f limpa.sed
              2§(c) div§dividendos§MBalDN§Uma das ...§
              194§arch's cert§dec serv prest§Jur§null§
              3§(deb) prem§prêmio (deb)§MBalDN§Este ...§
              4§(e)§alínea "e"§Jur§null§
              5§(srhol, stkhol)>eq.§patlíq§MBalDN§null§

              beleza! todos os campos separados por §, um delimitador único.
              daqui pra frente, ou faz como vc tava querendo, mapeando todos
              os grupos de uma vez ou faz como o thobias fez, usando o reserva.


              > e substitui por:
              >
              \t<termo>\n\t\t<number>\2</number>\n\t\t<English>\4</English>\n\t\t<Portugue
              >
              se>\6</Portuguese>\n\t\t<Glossary>\8</Glossary>\n\t\t<Comentario>\10</Coment
              > ario>

              cada campo é marcado como \([^§]\+\)§ então vou fazer só o
              comecinho que dá muita canseira:

              # sed -f limpa.sed lixo |
              sed 's|^\([^§]\+\)§\([^§]\+\)§.*|<number>\1<english>\2...|'
              <number>2<english>(c) div...
              <number>194<english>arch's cert...
              <number>3<english>(deb) prem...
              <number>4<english>(e)...
              <number>5<english>(srhol, stkhol)>eq....


              claro, aí você bota o formato que você quiser, pois os campos
              já estão corretamente mapeados.

              ufa! que troço mala.

              > Pergunta especialmente dedicada ao brontossauro Aurélio, que
              > despreza PCRE com toda aquela desfaçatez que lhe é característica.
              > :-)))

              desculpa a demora, mas coisinhas mais complicadas assim requerem
              mais tempo e mais escapadas do chefe :)

              falouzz.

              =====
              --
              ATENCAO: o www.verde666.org vai morrer, use www.aurelio.net
              ATTENTION: www.verde666.org is no more, use www.aurelio.net

              _______________________________________________________________________
              Yahoo! Mail
              O melhor e-mail gratuito da internet: 6MB de espaço, antivírus, acesso POP3, filtro contra spam.
              http://br.mail.yahoo.com/
            • aurelio
              ae thobias, ... essa ER pode ser diminuída se vc repetir parte dela com as chaves: s/^ ([^§] +§ ) {2 } ([^§] + )§.*/ 2 /p g
              Mensagem 6 de 9 , 8 de mai de 2003
                ae thobias,

                só um toque:

                --- Thobias Salazar Trevisan <thobias@...> escreveu:

                > s/^[^§]\+§[^§]\+§\([^§]\+\)§.*/<Portugue>\1<\/Portuguese>/p
                > g
                > s/^[^§]\+§[^§]\+§[^§]\+§\([^§]\+\)§.*/<Glossary>\1<\/Glossary>/p
                > g

                essa ER pode ser diminuída se vc repetir parte dela com as chaves:

                s/^\([^§]\+§\)\{2\}\([^§]\+\)§.*/<Portugue>\2<\/Portuguese>/p
                g
                s/^\([^§]\+§\)\{3\}\([^§]\+\)§.*/<Glossary>\2<\/Glossary>/p
                g

                e só vai mudando o {número}

                falouzz.


                =====
                --
                ATENCAO: o www.verde666.org vai morrer, use www.aurelio.net
                ATTENTION: www.verde666.org is no more, use www.aurelio.net

                _______________________________________________________________________
                Yahoo! Mail
                O melhor e-mail gratuito da internet: 6MB de espaço, antivírus, acesso POP3, filtro contra spam.
                http://br.mail.yahoo.com/
              • Luciano ES
                Puxa, Aurélio, essa msg deve ter sido muito chata para você escrever, mas eu gostei muito de ler... porque entendi tudo! Sua abordagem é muito boa mesmo,
                Mensagem 7 de 9 , 13 de mai de 2003
                  Puxa, Aurélio, essa msg deve ter sido muito chata para você escrever,
                  mas eu gostei muito de ler... porque entendi tudo! Sua abordagem é muito
                  boa mesmo, você é um mestre zen... Só no finalzinho a coisa ficou um
                  pouco confusa, e teve um troço que você fez ali que eu nunca teria
                  pensado sozinho, mas tudo bem. Logo depois entendi e vi o pulo do gato.
                  Talvez eu precise mesmo rever os meus conceitos. Eu tenho mania de querer
                  fazer tudo numa regex só, tipo um raio laser de alta precisão que vai
                  com tudo mas corta direitinho sem errar e deixa o produto acabado, sem
                  sobra, sem talhos nem rebarbas. Mas talvez essa não seja mesmo a melhor
                  forma. Bela aula, como sempre. Obrigadão!

                  --
                  Luciano Espirito Santo
                  Santos, SP - Brasil

                  <-quote-> **************************************************
                  On 08/05/03 at 16:49, aurelio wrote in 8K:
                  Assunto/Subject: Re: [sed-br] 2 aspas, sem PCRE

                  >ae luciano,
                  >
                  >finalmente vou limpar o INBOX... espero que ainda te sirva.
                  >
                  >AVISO: e-mail looooongo e chato, leia quando estiver com tempo.
                  >...

                  [a mensagem original foi editada para poupar espaço e utilização de
                  recursos; consulte os arquivos da lista se quiser vê-la inteira]

                  ********* END OF ORIGINAL MESSAGE *********</-quote->
                • aurelio
                  ae luciano, ... beleza cara! então valeu o esforço :) ... olha, isso é mesmo uma coisa engraçada e acho que até vale a pena por no livro. antes eu pensava
                  Mensagem 8 de 9 , 14 de mai de 2003
                    ae luciano,

                    --- Luciano ES <luc-groups@...> escreveu:
                    > Puxa, Aurélio, essa msg deve ter sido muito chata para você
                    > escrever, mas eu gostei muito de ler... porque entendi tudo!

                    beleza cara! então valeu o esforço :)

                    > Talvez eu precise mesmo rever os meus conceitos. Eu tenho mania
                    > de querer fazer tudo numa regex só, tipo um raio laser de alta
                    > precisão que vai com tudo mas corta direitinho sem errar e deixa
                    > o produto acabado, sem sobra, sem talhos nem rebarbas. Mas talvez
                    > essa não seja mesmo a melhor forma.

                    olha, isso é mesmo uma coisa engraçada e acho que até vale a pena
                    por no livro.

                    antes eu pensava exatamente assim como você descreveu. sempre
                    fazia tudo num s/// só, marcando altos grupos e abusando dos
                    retrovisores depois.

                    depois, lendo mensagens na sed-users, vendo as técnicas dos
                    outros e com a experiência das funções ZZ, acabei migrando
                    para a tática do
                    vai-cortando-todos-os-lixos-até-que-sobre-o-que-vc-quer-no-final

                    alguns motivos, alguns técnicos, outros meramente emocionais do
                    porque fazer isso.

                    exemplo para os que não entenderam direito do que estamos falando:

                    texto: "Oi, tudo bem? Tudo bem! Fora o tédio! Que me consome..."
                    o que eu quero: "Tudo Bem!"

                    tática 1 - laser de alta precisão:

                    sed -n 's/^Oi.*? \([^!]*!\) .*/\1/p'

                    tática 2 - faxina:

                    sed '/^Oi/!d ; s/!.*/!/ ; s/.*? //'


                    diferenças:

                    1. usar o -n é palha. sempre qdo se precisa do grep+sed, lá
                    vem o -n. eu prefiro usar o /.../!d e depois limpar somente
                    as linhas que interessam
                    2. a eliminação "em partes" tende a precisar de ERs mais simples,
                    logo se torna mais fácil de compor
                    3. diz a lenda que usar o retrovisor deixa o sed mais lento,
                    então sempre que puder evitá-lo é uma boa
                    4. note que no 1o foi necessário usar o [^!] por que o .* iria
                    até a segunda exclamação. no 2o o s/!.*// resolve isso fácil
                    5. para problemas complicados como o seu, nem sempre dá pra
                    fazer todas as exceções numa ER somente, e acaba sendo mais
                    easy-riding fazer pequenos pedacinhos e ir acompanhando a
                    evolução do script até chegar no nirvana
                    6. entender as coisas por partes é mais fácil do que encarar
                    um comandão de 80 carcteres de uma vez (vide palavras longas
                    em alemão :)
                    7. na tática 2 geralmente se usa o .* para especificar partes
                    do lixo, e usar .* é massa :)

                    ah, no fim, use o que você mais gosta :)


                    =====
                    --
                    ATENCAO: o www.verde666.org vai morrer, use www.aurelio.net
                    ATTENTION: www.verde666.org is no more, use www.aurelio.net

                    _______________________________________________________________________
                    Yahoo! Mail
                    O melhor e-mail gratuito da internet: 6MB de espaço, antivírus, acesso POP3, filtro contra spam.
                    http://br.mail.yahoo.com/
                  • Luciano ES
                    Nossa, cara, que idéia! Regex em alemão deve ser divertidíssimo!!! ... -- Luciano Espirito Santo Santos, SP - Brasil
                    Mensagem 9 de 9 , 14 de mai de 2003
                      Nossa, cara, que idéia! Regex em alemão deve ser divertidíssimo!!!
                      :-))

                      --
                      Luciano Espirito Santo
                      Santos, SP - Brasil

                      <-quote-> **************************************************
                      On 14/05/03 at 17:22, aurelio wrote in 5K:
                      Assunto/Subject: Re: [sed-br] Re: 2 aspas, sem PCRE

                      > 6. entender as coisas por partes é mais fácil do que encarar
                      > um comandão de 80 carcteres de uma vez (vide palavras longas
                      > em alemão :)

                      ********* END OF ORIGINAL MESSAGE *********</-quote->
                    Sua mensagem foi enviada com êxito e será entregue aos destinatários em breve.