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誰かがまだそれが優雅ではないと思っている場合、私はそれを助けることができません。

関連情報