여러 줄 텍스트 파일에서 중첩된 중괄호 사이의 모든 텍스트를 제거하는 방법은 무엇입니까?

여러 줄 텍스트 파일에서 중첩된 중괄호 사이의 모든 텍스트를 제거하는 방법은 무엇입니까?

이 질문은 다음에서 비롯됩니다. 여러 줄 텍스트 파일에서 중괄호 사이의 모든 텍스트를 삭제하는 방법은 무엇입니까?(동일하지만 중첩 요구 사항은 없습니다).

예:

This is {
{the multiline
text} file }
that wants
{ to {be
changed}
} anyway.

다음과 같아야 합니다:

This is 
that wants
 anyway.

이를 수행하는 데 사용할 수 있는 일종의 한 줄 bash 명령(awk, sed, perl, grep, cut, tr...등)이 있습니까?

답변1

$ sed ':again;$!N;$!b again; :b; s/{[^{}]*}//g; t b' file3
This is 
that wants
 anyway.

설명하다:

  • :again;$!N;$!b again

    전체 파일을 읽습니다.

    :again라벨입니다. N다음 줄을 읽고, $!N마지막 줄에 도달하지 않은 경우 다음 줄을 읽습니다. 마지막 줄이 아닌 경우 레이블 $!b again로 다시 분기합니다 .again

  • :b

    이는 label 을 정의합니다 b.

  • s/{[^{}]*}//g

    이렇게 하면 텍스트에 내부 중괄호가 포함되어 있지 않은 한 중괄호 안의 텍스트가 제거됩니다.

  • t b

    위의 대체 명령으로 인해 변경이 발생하면 label 로 다시 이동하세요 b. 이런 방식으로 모든 가새 그룹이 제거될 때까지 바꾸기 명령을 반복합니다.

답변2

펄 방법:

$ perl -F"" -a00ne 'for (@F){$i++ if /{/; $i||print; $i-- if /}/}' file
This is 
that wants
 anyway

설명하다

  • -a-F: 배열에 지정된 파일 구분 기호에 대한 자동 분할을 켭니다 @F.
  • -F""@F: 입력 필드 구분 기호를 공백으로 설정합니다. 그러면 각 요소가 입력 문자 중 하나 가 됩니다 .
  • -00: "줄"이 두 개의 연속 줄 바꿈으로 정의되는 단락 모드를 켭니다. 이는 이 경우 전체 파일이 한 줄로 처리된다는 것을 의미합니다. 파일에 여러 단락이 있을 수 있고 대괄호가 여러 단락에 걸쳐 있을 수 있는 경우 대신 를 사용하세요 -0777.
  • -ne: 입력 파일을 읽고 주어진 스크립트를 -e각 줄에 적용합니다.

스크립트 자체는 실제로 매우 간단합니다. 카운터는 a가 보일 때마다 1씩 증가하고 {, 보일 때마다 1씩 감소합니다 }. 이는 카운터가 0일 때 대괄호 안에 있지 않으며 다음을 인쇄해야 함을 의미합니다.

  • for (@F){}: @F줄의 모든 요소, 모든 문자에 대해 이 작업을 수행합니다.
  • $i++ if /{/;: $i캐릭터가 1개라면 1개 추가{
  • $i||print;: $i설정되지 않은 경우 인쇄합니다(0은 설정되지 않은 것으로 간주).
  • $i-- if /}/: $i문자가 1이면 1씩 감소}

관련 정보