Sed (ou outro) script para substituir um caractere dentro do grupo de captura

0

Estou tentando converter marcação Pandoc para marcação wiki do Confluence, estou usando markdown2confluence para fazer a maior parte do trabalho . Isso funciona muito bem, exceto quando estou falando de CSS e FreeMarker que usam { & } no código enquanto o Confluence usa {{ & }} para marcar o início / fim do bloco de códigos. Portanto, preciso corresponder a um padrão entre {{...}} .

Se eu soubesse (mais) Ruby, eu poderia consertá-lo lá, mas eu sou um cara Unix da velha escola, então pensei em awk ou sed.

Então eu cheguei até:

   sed 's/{{\([^}}]*\)}}/{{""}}/g' tmp.wkd

que leva:

First we need a way to select a state (or group of states) CSS uses what
is called a selector to choose which elements to apply to, we have been
using one up until now without noticing, it is the {{*}} at the beginning
of our CSS. This is a special selector that means select everything. So
the rule that follows it (the bit between {{{}} and {{}}} apply to every
polygon on the map. But CSS allows us to insert a filter instead by
using {{[...]}} instead of {{*}}.

e produz:

First we need a way to select a state (or group of states) CSS uses what
is called a selector to choose which elements to apply to, we have been
using one up until now without noticing, it is the {{"*"}} at the beginning
of our CSS. This is a special selector that means select everything. So
the rule that follows it (the bit between {{"{"}} and {{""}}} apply to every
polygon on the map. But CSS allows us to insert a filter instead by
using {{"[...]"}} instead of {{"*"}}.

Mas o que eu preciso é:

First we need a way to select a state (or group of states) CSS uses what
is called a selector to choose which elements to apply to, we have been
using one up until now without noticing, it is the {{*}} at the beginning
of our CSS. This is a special selector that means select everything. So
the rule that follows it (the bit between {{\{}} and {{\}}} apply to every
polygon on the map. But CSS allows us to insert a filter instead by
using {{[...]}} instead of {{*}}.

Também precisa lidar com {{${type.name}}} , que deve se tornar {{$\{type.name\}}} .

Existem dois problemas

  1. Preciso substituir { por \{ em vez de usar aspas, por isso preciso modificar de alguma forma.
  2. O desagradável look {{}}} (que deve vir {{\}}} não sai certo, não importa o quanto eu tente terminar a correspondência de padrões.
por Ian Turton 09.12.2015 / 15:39

1 resposta

2

O seguinte comando sed parece funcionar:

   sed 's/{{\([^*[a-z][^}]*\)}}/{{\}}/g;s/{{\${\([^}]*\)}}}/{{$\{\}}}/g'

Explicação:

  1. {{\([^*[a-z][^}]*\)}} encontra {{stuff}} , exceto quando stuff começa com * ou [ ou uma letra minúscula.
  2. Substitua por {{\stuff}} .
  3. Em seguida, {{\${\([^}]*\)}}} encontra {{\${junk}}} .
  4. E substitui por {{$\{junk\}}} .

Editar : Uma solução alternativa, após esclarecimento do OP, poderia ser esta:

   sed 's/\({{[^}]*\){\([^}]*}}\)/\{/g;s/\({{[^}]*\)}}}/\}}}/g'

Como todos sabemos, o sed não pode fazer a análise recursiva, mas isso deve funcionar para a maioria dos casos simples.

Explicação:

  1. \({{[^}]*\){\([^}]*}}\) encontra {{foo{bar}} , em que foo e bar não contêm } .
  2. E substitui por {{foo\{bar}} . (Nota {{xxx{yyy}}} é tratado ok.)
  3. Em seguida, \({{[^}]*\)}}} encontra {{baz}}} , em que baz não contém } .
  4. E substitui por {{baz\}}} .

foo , bar e baz podem estar vazios, portanto, por exemplo, {{}}} é convertido em {{\}}} , conforme necessário.

    
por 09.12.2015 / 16:38