sed 정규식 주소 범위에서 줄 수 빼기(또는 더하기)

sed 정규식 주소 범위에서 줄 수 빼기(또는 더하기)

다음 내용이 포함된 ICS 파일이 여러 개 있습니다.

...
PRIORITY:4
DESCRIPTION:this
  was
  a
  triumph
COMPLETED:20180101T160000
...

나는 DESCRIPTION주요 문제를 해결하는 데 관심이 있습니다. 이 키는 DESCRIPTIONICS 파일의 어느 곳에나 나타날 수 있습니다. 이것은아니요항상 열쇠를 따르십시오 COMPLETED.

를 사용하려면 ed다음을 수행합니다.

/DESCRIPTION/;/^[^ ]/-1p

결과 :

DESCRIPTION:this
  was
  a
  triumph

그런데 sed이런 능력은 없는 것 같습니다.

sed -n '/DESCRIPTION/,/^[^ ]/-1p' filename

밝혀지다

sed: -e 표현식 #1, 문자 22: 알 수 없는 명령: `-'

내가 원하는 것을 할 수 있는 방법이 있나요 sed?

이 특정 문제를 해결하려면

이 문제는 다음을 통해 해결될 수 있습니다.

sed -n '/DESCRIPTION:/,/^\S/ { /\(DESCRIPTION\|^\s\)/p }' example.ics

하지만 매우 투박하고 긴 느낌이 듭니다.

awk이 역시 지원되지 않는 것 같으니 /begpat/,/endpat/-1다음과 같은 결과가 나올 것입니다.

BEGIN { endpat = "^(DESCRIPTION|\\s)" }
/^DESCRIPTION/, $0 !~ endpat {
    if ($0 ~ endpat) {print}
}

답변1

당신은 이미 꽤 가까워졌습니다.

sed '/DESCRIPTION/p;//,/^[^ ]/!d;//d' filename

당신이 원하는 것을 할 것입니다. 왜?

  • 범위를 정의하고 해당 범위 밖의 모든 항목을 삭제할 수 있습니다./start/,/stop/!d
  • 그런 다음 일치하는 마지막 줄도 제거하려고 합니다. 다음은 //d이를 수행합니다(빈 패턴이 //마지막 패턴과 일치하므로 이 /stop/줄이 됩니다).
  • 그러나 귀하의 경우 패턴은 첫 번째 행과도 일치합니다. 운명! 먼저 인쇄 해 보겠습니다 p. 그러면 제가 보여드린 명령을 받게 됩니다(다시 빈 모드 사용).

다양한 방법을 사용하여 업데이트

귀하의 의견에서는 이를 "해결 방법"이라고 부르는데, 이는 어떤 관점에서 볼 때 의미됩니다. 사실, 나 자신을 위해서는 좀 더 다른 sed접근 방식을 선택하겠습니다.

sed '/^ /{H;d;};x;/^DESCRIPTION/!d' filename

이는 커플에게는 자연스러운 일이지만 sed일부에게는 처음에는 이상하게 보일 수도 있습니다. 다음은 "내가 기억할 수 있기를 바라"-방법. 그게 무엇입니까? 들여쓰기가 없는 줄을 만날 때마다 "이전 줄을 기억할 수 있었으면 좋겠다, 인쇄할 가치가 있었으면 좋겠어"라고 생각합니다. 그러면 우리는 단순히 그 줄을 기억했다고 가정합니다. 그들은 공간을 확보하여 다음을 수행할 수 있습니다. 단순히 x패턴 공간을 변경하고 공간을 예약하고, d시작하지 않으면 제거하세요 DESCRIPTION(시작하면 기본적으로 인쇄됩니다).

장점은 x들여쓰기되지 않은 모든 줄이 자동으로 예약된 공간에 있으므로 예약된 공간에 들여쓰기된 줄만 추가하면 된다는 것입니다 H. 이것이 바로 이 /^ /{H;d;}부분의 목적입니다( d이 라인의 출력이나 추가 처리를 피하기 위해).

오늘날 프로그래머들은 그 반대의 일을 합니다. 다음과 같은 루프를 수행할 수 있습니다.

sed '/DESCRIPTION/!d
  :loop
  N;/\n[^ ].*/!bloop
s///' filename

즉, DESCRIPTION키워드가 나타날 때까지 모든 것을 삭제한 다음 루프를 시작하여 로 줄을 수집 N하고 공백이 아닌 줄이 있을 때까지 반복합니다 \n[^ ].*. 이 경우 마지막 행을 삭제합니다(다시 빈 패턴 활용).

이것도 작동하지만 작동하지 않습니다 sed.

답변2

예, sed는 다음과 같은 주소 범위를 지원합니다.

sed -n '/string1/,/string2/p file

귀하의 경우에는 -E정규식을 확장하는 옵션을 사용해 보십시오.

sed -nE '/this/,/^[^ ]/p' filename

관련 정보