Script Sed (u otro) para reemplazar un personaje dentro del grupo de captura

Script Sed (u otro) para reemplazar un personaje dentro del grupo de captura

Estoy intentando convertir el marcado Pandoc al marcado wiki de Confluence, estoy usandomarkdown2confluenciapara hacer la mayor parte del trabajo. Esto funciona bastante bien excepto cuando hablo de CSS y FreeMarker que usan {& }en el código mientras que Confluence usa {{& }}para marcar el inicio/final del bloque de código. Entonces necesito hacer coincidir un patrón encerrado en {{...}}.

Si conociera (más) Ruby, posiblemente podría arreglarlo allí, pero soy un tipo de Unix de la vieja escuela, así que pensé en awk o sed.

Entonces llegué tan lejos como:

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

el cual toma:

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 {{*}}.

y produce:

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 {{"*"}}.

Pero lo que necesito es:

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 {{*}}.

También es necesario manejar {{${type.name}}}cuál debería convertirse en {{$\{type.name\}}}.

Hay dos problemas

  1. Necesito reemplazar {con \{en lugar de usar comillas, así que necesito modificar \1de alguna manera.
  2. El aspecto desagradable {{}}}(que debería ser) {{\}}}no sale bien, no importa cuánto intente finalizar la coincidencia del patrón.

Respuesta1

El siguiente comando sed parece funcionar:

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

Explicación:

  1. {{\([^*[a-z][^}]*\)}}busca {{stuff}}, excepto cuando stuffcomienza con *o [o una letra minúscula.
  2. Reemplácelo con {{\stuff}}.
  3. Luego {{\\${\([^}]*\)}}}encuentra {{\${junk}}}.
  4. Y lo reemplaza con {{$\{junk\}}}.

Editar: Una solución alternativa, después de la aclaración del OP, podría ser esta:

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

Como todos sabemos, sed no puede realizar un análisis recursivo, pero debería funcionar en la mayoría de los casos simples.

Explicación:

  1. \({{[^}]*\){\([^}]*}}\)encuentra {{foo{bar}}, donde fooy barno contiene }.
  2. Y lo reemplaza con {{foo\{bar}}. (La nota {{xxx{yyy}}}se maneja bien).
  3. Luego \({{[^}]*\)}}}encuentra {{baz}}}, donde bazno contiene }.
  4. Y lo reemplaza con {{baz\}}}.

foo, bary bazpueden estar vacíos, por lo que, por ejemplo, {{}}}se convierte en {{\}}}, según sea necesario.

información relacionada