캡처 그룹 내의 문자를 대체하는 Sed(또는 기타) 스크립트

캡처 그룹 내의 문자를 대체하는 Sed(또는 기타) 스크립트

Pandoc 마크업을 Confluence wiki 마크업으로 변환하려고 합니다.markdown2confluence대부분의 작업을 수행합니다. Confluence가 코드 블록의 시작/끝을 표시하기 위해 &를 ​​사용하는 동안 코드에서 {&를 사용하는 CSS 및 FreeMarker에 대해 이야기하는 경우를 제외하면 이는 꽤 잘 작동합니다. 그래서 에 포함된 패턴을 일치시켜야 합니다 .}{{}}{{...}}

내가 (더) Ruby를 안다면 거기에서 고칠 수도 있겠지만 나는 구식 유닉스 사용자이기 때문에 awk나 sed를 생각했습니다.

그래서 나는 다음과 같은 것을 얻었습니다.

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

소요되는 시간은 다음과 같습니다.

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

그리고 다음을 생산합니다:

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

하지만 나에게 필요한 것은:

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

{{${type.name}}}또한 가 되어야 하는 처리도 필요합니다 {{$\{type.name\}}}.

두 가지 문제가 있습니다

  1. {따옴표를 사용하는 대신 로 바꿔야 하므로 어떻게든 \{수정해야 합니다 \1.
  2. 아무리 패턴 매치를 끝내려고 해도 나오지 않을 것 같은 추악한 모습이 {{}}}나옵니다 .{{\}}}

답변1

다음 sed 명령이 작동하는 것 같습니다.

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

설명:

  1. {{\([^*[a-z][^}]*\)}}또는 소문자 로 시작하는 {{stuff}}경우를 제외하고 를 찾습니다 .stuff*[
  2. 로 교체하세요 {{\stuff}}.
  3. 그런 {{\\${\([^}]*\)}}}다음 {{\${junk}}}.
  4. 그리고 로 대체합니다 {{$\{junk\}}}.

편집하다: OP에서 설명한 후 대체 솔루션은 다음과 같습니다.

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

우리 모두 알고 있듯이 sed는 재귀 구문 분석을 수행할 수 없지만 이는 대부분의 간단한 경우에 작동합니다.

설명:

  1. \({{[^}]*\){\([^}]*}}\)를 찾고 {{foo{bar}}, 어디에 있고 foo, bar포함하지 않습니다 }.
  2. 그리고 로 대체합니다 {{foo\{bar}}. (메모는 {{xxx{yyy}}}잘 처리되었습니다.)
  3. 그런 다음 가 포함되지 않은 을 \({{[^}]*\)}}}찾습니다 .{{baz}}}baz}
  4. 그리고 로 대체합니다 {{baz\}}}.

foo, bar및 는 baz비어 있을 수 있으므로 예를 들어 필요에 따라 {{}}}는 으로 변환됩니다 {{\}}}.

관련 정보