여러 줄로 된 텍스트 파일에서 중첩 중괄호 사이의 모든 텍스트를 어떻게 삭제합니까? 요구 사항 없음). 예: This is { {the multiline text} file

이 질문은 여러 줄로 된 텍스트 파일에서 중괄호 사이의 모든 텍스트
어떻게 삭제할 수 있습니까? (단지 동일하지만 중첩 요구 사항 없음).

예:

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

되어야한다 :

This is
that wants
 anyway.

일종의 한 줄 bash 명령 (awk, sed, perl, grep, cut, tr … 등) 으로이 작업을 수행 할 수 있습니까?



답변

$ 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

    이것은 레이블을 정의합니다 b.

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

    텍스트에 내부 중괄호가 포함되어 있지 않으면 중괄호 안의 텍스트가 제거됩니다.

  • t b

    위의 대체 명령으로 변경이 발생한 경우 label으로 이동하십시오 b. 이런 식으로 대체 명령은 모든 가새 그룹이 제거 될 때까지 반복됩니다.


답변

펄 접근 방식 :

$ 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 씩 증가하고마다 하나씩 감소합니다 }. 이것은 카운터가 0 일 때 대괄호 안에 있지 않으며 다음을 인쇄해야 함을 의미합니다.

  • for (@F){}:의 각 요소 @F, 행의 각 문자에 대해이 작업을 수행하십시오 .
  • $i++ if /{/;: $i이 문자가 a이면 1 씩 증가{
  • $i||print;: $i설정 되지 않은 경우 인쇄 합니다 (0은 설정 되지 않은 것으로 계산).
  • $i-- if /}/: $i이 문자가 a 인 경우 1 씩 감소}