예를 들어 전송은 다음과 같습니다.
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.500
sed
또한 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
시작 타임스탬프,\2
is 텍스트 줄,\3
is 개행 문자(대체 시 필요하지만 POSIX는\n
대체 시 정의되지 않음),\4
is 종료 타임스탬프입니다. 실제보다 더 복잡해 보입니다.p
s
패턴 공간을 교체 한 다음 제거 하는 옵션을 추가하면d
예약된 공간이 아직 비어 있는 동안 첫 번째 줄에서 원치 않는 출력을 방지할 수 있습니다.- 이제 남은 것은 다른 행을
H
이전 공간 에 추가하고 - 마지막 라인의 경우 e는
x
버퍼를 다시 변경하여 타임스탬프를 닫지 않고도 예약된 공간에 수집된 라인이 인쇄되도록 합니다.
sed
누군가가 여전히 그것이 우아하지 않다고 생각한다면 , 나는 그것을 도울 수 없습니다.