web-dev-qa-db-ja.com

データ行の前にヘッダー行を追加して、テキストファイルを再配置します

内容が次のようなファイルがあります。

2009 150  0  0  0     0000
75.316   0.0400390625  0.00007        0.00000 0.8980
76.216   0.0400390625  0.00007        1.00000 0.9046
77.217   0.0400390625  0.00009        2.00000 0.9113
78.341   0.0400390625  0.00010        3.00000 0.9183
2009 150  2  0  0     0000
75.316   0.0400390625  0.00007        0.00000 0.8980
76.216   0.0400390625  0.00007        1.00000 0.9046
77.217   0.0400390625  0.00009        2.00000 0.9113
78.341   0.0400390625  0.00010        3.00000 0.9183
79.616   0.0400390625  0.00013        4.00000 0.9255

私はしたいと思います:

  1. キーワード2009で始まるすべての行を検索します。
  2. 2009で始まる行の別のオカレンスが見つかるまで、これらの行を後続のすべての行にプリペンドし、以下同様にEOFまで続けます。

本質的に、私はこのような出力を探しています:

2009 150  0  0  0     0000 75.316   0.0400390625  0.00007        0.00000 0.8980
2009 150  0  0  0     0000 76.216   0.0400390625  0.00007        1.00000 0.9046
2009 150  0  0  0     0000 77.217   0.0400390625  0.00009        2.00000 0.9113
2009 150  0  0  0     0000 78.341   0.0400390625  0.00010        3.00000 0.9183
2009 150  2  0  0     0000 75.316   0.0400390625  0.00007        0.00000 0.8980
2009 150  2  0  0     0000 76.216   0.0400390625  0.00007        1.00000 0.9046

....。

私はかなり長い間これに頭を悩ませてきました、そして解決策を思い付くことができません。助けていただければ幸いです。フラグを使用してキーワード間のテキストを抽出する方法は知っていますが、それが正しい方向かどうかはわかりません。

4
user65305

これにはawkを使用できます。

awk '/^2009/{a=$0;next}{print a" "$0} ' file.txt

これは、2009年の最初の一致の前に、任意の行の前にスペースを追加するだけです。デフォルトの文字列を次のように追加するように設定できます。

awk 'BEGIN{a="My default prepend string";}/^2009/{a=$0;next}{print a" "$0} ' file.txt
5
Josh Jolly

sedの使用:

_sed -n '
  /^2009/ { h }
  /^2009/ !{ G; s/^\(.*\)\n\(.*\)$/\2 \1/p }
  ' in_file
_

要求に応じた説明:

_-n_-指示がない限り、sedは何も出力しません。

_/^2009/ { h }_-_2009_で始まる行に到達したら、それを保留バッファーに入れます。

_/^2009/ !{...}_-_{...}_内のパターンは、_2009_で始まらないすべての行に適用されます。

G; s/^\(.*\)\n\(.*\)$/\2 \1/p --Gはホールドバッファをコピーし、パターンスペースに読み取ったばかりの行を追加します。パターンスペースに2行あり、印刷する前に順序を入れ替えて組み合わせる必要があります。後方参照による置換パターンはまさにこれを行います。

4
Graeme

私はこれをPerlで行います:

Perl -lne 'if(/^2009/){$n=$_; next} print "$n $_"' file

または、より簡潔に

Perl -lne '/^2009/ ? ($n=$_) : print "$n $_"' file

現在の行(Perlでは$_)が$nで始まる場合は2009として保存し、そうでない場合は$nの現在の値とともに現在の行を出力するという考え方です。

4
terdon