sed와 일치하는 이전 줄과 일치하는 일부 줄을 추가하는 방법은 무엇입니까?

sed와 일치하는 이전 줄과 일치하는 일부 줄을 추가하는 방법은 무엇입니까?

예를 들어 전송은 다음과 같습니다.

00:00:10.730
this presentation is delivered by the

00:00:13.230
Stanford center for professional

00:00:14.610
development okay so let's get started

00:00:25.500
with today's material so um welcome back

00:00:32.399
to the second lecture what I want to do

도착하다

00:00:10.730 --> 00:00:13.230
this presentation is delivered by the

00:00:13.230 --> 00:00:14.610
Stanford center for professional

00:00:14.610 --> 00:00:25.500
development okay so let's get started

00:00:25.500 --> 00:00:32.399
with today's material so um welcome back

00:00:32.399
to the second lecture what I want to do

답변1

코드 명확성을 위해 다음을 사용합니다 GNU sed.

sed -nE '

   /^([0-9][0-9]:){2}[0-9]+[.][0-9]+/!{p;d;}

   h;:a
      $bb;n;H
   /^([0-9][0-9]:){2}[0-9]+[.][0-9]+/!ba

   :b
   x
   y/\n_/_\n/
   s/^([^_]*)_(.*)_([^_]*)$/\1 ---> \3_\2/
   y/\n_/_\n/

   p;g;$!s/^/\n/;D

' yourfile

결과

00:00:10.730 ---> 00:00:13.230
this presentation is delivered by the

00:00:13.230 ---> 00:00:14.610
Stanford center for professional

00:00:14.610 ---> 00:00:25.500
development okay so let's get started

00:00:25.500 ---> 00:00:32.399
with today's material so um welcome back

00:00:32.399
to the second lecture what I want to do

설명하다

  • 숫자에서 다음 숫자까지 행 범위를 유지합니다.
  • 그런 다음 범위의 끝에서 마지막 부분이 앞으로 밀리고 범위가 인쇄되면서 패턴 공간을 지우고 범위의 끝으로 채운 다음 해당 패턴 공간의 값을 사용하여 제어가 최상위 sed로 전달됩니다. 현재 범위의 끝에서 다시 시작하기 위한 코드 다음 숫자까지 또는 eof에 도달할 때까지 반복합니다.

답변2

싱글로멍하니상대적으로 "작은"(크기별) 파일을 위한 방법:

awk 'BEGIN{ RS=""; FS="[[:space:]]+" }
     {   c++; 
         a[c]["t"]=$1; 
         a[c]["s"]=substr($0,length($1)+2) 
     }
     END { 
         len=length(a); 
         for(i=1;i<=len;i++) { 
             if((i+1)<=len){ printf("%s --> %s\n%s\n\n",a[i]["t"],a[i+1]["t"],a[i]["s"]) } 
             else { printf("%s\n%s\n",a[i]["t"],a[i]["s"]) }
         } 
     }' file

산출:

00:00:10.730 --> 00:00:13.230
this presentation is delivered by the

00:00:13.230 --> 00:00:14.610
Stanford center for professional

00:00:14.610 --> 00:00:25.500
development okay so let's get started

00:00:25.500 --> 00:00:32.399
with today's material so um welcome back

00:00:32.399
to the second lecture what I want to do

답변3

GNU를 사용 sed하고 다음을 수행하십시오 tac.

tac file | \
sed -E '/^[0-9]{2}:[0-9]{2}:[0-9]{2}\.[0-9]{3}$/ { H; x; s/^\n//; s/\n/ --> /; }' | \
tac

동일한 내용을 관례적으로 sed(즉, 없이 ) 작성할 수 있지만 더 장황해집니다.-E

GNU를 사용 awk하고 다음을 수행하십시오 tac.

tac file | \
gawk --re-interval '
    /^[0-9]{2}:[0-9]{2}:[0-9]{2}\.[0-9]{3} --> / { old = $1 }
    /^[0-9]{2}:[0-9]{2}:[0-9]{2}\.[0-9]{3}$/ { if(old != "") $0 = $0 " --> " old; old = $1 }
    1' | \
tac

이 버전은 awk입력 파일의 간격을 처리할 수 있지만 이 버전은 이에 속습니다.00:00:14.610 --> 00:00:25.500sed

또한 tac다음을 사용하여 시뮬레이션을 수행할 수 있습니다 sed.

sed -n '1!G; $p; h'

또는 다음과 같습니다:

sed '1!G; h; $!d'

그러나 두 형식 모두 전체 입력 파일을 메모리에 로드하므로 그다지 효율적이지 않습니다.

결과:

00:00:10.730 --> 00:00:13.230
this presentation is delivered by the

00:00:13.230 --> 00:00:14.610
Stanford center for professional

00:00:14.610 --> 00:00:25.500
development okay so let's get started

00:00:25.500 --> 00:00:32.399
with today's material so um welcome back

00:00:32.399
to the second lecture what I want to do

답변4

주어진 답변에서 다른 도구에 대한 루프나 파이프를 볼 수 있으며 필요하지 않으면 마음에 들지 않습니다. 나는 다음과 같은 대사를 좋아한다:

sed -E '/^[0-9:.]+$/{x;G;s/(.*)\n(.*)\n(\n)(.*)/\1 --> \4\3\2\3/p;d;};H;$!d;x'

하지만 단계별로 살펴보겠습니다.

  • ^[0-9:.]+$타임스탬프 행에 확장 정규식을 사용하고 있습니다 . 실제 세계에서는 이 정도면 충분하지만 자유롭게 더 정확하게 만들 수 있습니다. 주소에 이 패턴을 사용하여 {}쌍의 모든 항목이 타임스탬프 행에 대해서만 실행되도록 합니다.
  • 분명히 다음 타임스탬프가 도착할 때까지 모든 것을 염두에 두어야 합니다. 기억은 예약된 공간에 추가하는 것을 의미합니다.sed
  • 따라서 타임스탬프가 나타날 때마다 이전 타임스탬프 이후의 모든 항목이 저장 공간에 있다고 가정합니다. 따라서 현재 타임스탬프를 H이전 공간에 추가한 다음 x모드를 변경하고 공간을 예약합니다. 이런 식으로 현재 타임스탬프는 이미 다음 기간을 위해 보관 공간에 저장되어 있으며 필요한 모든 것은 패턴 공간에 있습니다.
  • s대체를 사용하여 재구성 하기만 하면 됩니다 . s/(.*)\n(.*)\n(\n)(.*)/\1 --> \4\3\2\3/--is \1시작 타임스탬프, \2is 텍스트 줄, \3is 개행 문자(대체 시 필요하지만 POSIX는 \n대체 시 정의되지 않음), \4is 종료 타임스탬프입니다. 실제보다 더 복잡해 보입니다.
  • ps패턴 공간을 교체 한 다음 제거 하는 옵션을 추가하면 d예약된 공간이 아직 비어 있는 동안 첫 번째 줄에서 원치 않는 출력을 방지할 수 있습니다.
  • 이제 남은 것은 다른 행을 H이전 공간 에 추가하고
  • 마지막 라인의 경우 e는 x버퍼를 다시 변경하여 타임스탬프를 닫지 않고도 예약된 공간에 수집된 라인이 인쇄되도록 합니다.

sed누군가가 여전히 그것이 우아하지 않다고 생각한다면 , 나는 그것을 도울 수 없습니다.

관련 정보