たとえば、転送は次のようになります。
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
誰かがまだそれが優雅ではないと思っている場合、私はそれを助けることができません。