列の2つの連続した行を追加し、前の行に分割して印刷します。

列の2つの連続した行を追加し、前の行に分割して印刷します。

ほぼ2000行の入力ファイルがあります。計算をして3番目の列に印刷する必要があります。

入力ファイルに関連する操作の例:

n ID1_1 n/(n+k)
k ID1_2

入力ファイル:

 10 ID1_1
 20 ID1_2
  1 ID3_1
  9 ID3_2
 20 ID20_1
 15 ID2_1
300 ID2_2

予想出力:

 10 ID1_1 0.33
 20 ID1_2 
200 ID3_1 0.11
  9 ID3_2
 20 ID20_1 /*I would just leave it like that*/
 15 ID2_1 0.047
300 ID2_2

簡単な解決策がありますか?ありがとうございます。

ベストアンサー1

表示された入力を考慮すると、次のことが機能します。

<infile sed -e '$!N;2i\' -e '3k 
s|\(\(.*  *\).*_1\)\n\(\(.*  *\).*_2\)$|[\1 ]P\2d\4+/p[\3]pc|;t
s|^[ _ID0-9]*|[&]pc|;P;D' | dc

私のために印刷されます...

 10 ID1_1 .333
 20 ID1_2
  1 ID3_1 .100
  9 ID3_2
 20 ID20_1
 15 ID2_1 .047
300 ID2_2

...dc精度を3に設定しましたが、精度が10だからです...

 10 ID1_1 .3333333333
 20 ID1_2
  1 ID3_1 .1000000000
  9 ID3_2
 20 ID20_1
 15 ID2_1 .0476190476
300 ID2_2

出力精度に加えて、あなたの精度とは異なります。期待される出力3行目 - しかし、これは質問のタイプミスのためのようです。

とにかく、これを理解するには、まず出力を2つの形式に解析する必要があることを考慮する必要があります。dc次のewlineなしでaを印刷するdcか、数字または1でaを印刷します。マクロで実行する以外は文字列として何もできません。しかし、数値を見ると非常に能力に優れています。P[string]\np[string]xdc

したがって、現在の行が最後の行の場合は、sedまず$!N現在の行に追加の行を追加します。 2行目はstdoutに文字列を挿入します。これは精度を3に設定するコマンドです。!$i3kdc

その後、交換しようとしています。

s|\(\(.*  *\).*_1\)\n\(\(.*  *\).*_2\)$|[\1 ]P\2d\4+/p[\3]pc|

_1これは、パターンスペースに現在少なくとも1つのスペースが含まれている場合にのみ成功します。ある地点ではすぐ後ろに並んだ文字が続き\n、ある地点ではその後に少なくとも1つの空白が続き、ある地点では直後に末尾が_2続き$ます。パターン空間の

これは、上記の置換が次の行のペアにのみ影響することを意味します。

...ID_1
...ID_2

...他の人でもありません。影響がある場合は、コンテンツを利用可能なdcスクリプトに変換します。次に、t交換が成功したことを確認し、成功すると、スクリプトから分岐して交換結果を印刷し、sedコマンドを実行しなくなります。標準出力を標準入力としてdc使用するため、たとえば、最初の2行を次のように変更します。sedsed

[ 10 ID_1 ]P10d20+/p[ 20 ID_2]pc

...dc次に、その入力を次のように処理します。

  • [ 10 ID_1 ]- 角かっこの間の文字列をスタックの一番上にスライドさせます。(これを行うと、すでにスタック内のすべてのアイテムが1つ下にプッシュされます。)
  • PP- 後ろに並んでいないスタックの上部を印刷して\nポップします。(これを行うと、下のスタックのすべての値が1ずつ増加します。)
  • 10- 数字10をスタックの一番上にスライドさせます。
  • dd- スタックの上部をコピーします。
  • 20- 数字20をスタックの一番上にスライドさせます。
  • +- スタックの上部に2cdを追加し、スタックの上部に2cdを追加します。(2つを同時に爆発させる)そして結果をスタックの一番上にスライドさせます。
  • /- スタックの上から2cdを分割します。(今私たちはdコピーします10スタックの上から(私たちの10 20 +結果) (2つを同時に爆発させる)そして結果をスタックの一番上にスライドさせます。
  • pp- スタックの上部を印刷します。(揚げずに)その後に行が表示されます\n
  • [ 20 ID_2]- 文字列をスタックの一番上にスライドさせます。
  • pp- スタックの上部を印刷します。(もう一度言うが爆発しないでください)その後は\nEwlineが続く
  • cc- スタックを理解する

したがって、dc以下を印刷してください。

 10 ID1_1 .333
 20 ID1_2

ただし、sedすでに説明したように、成功した一致がなく、パターンスペースが変更された場合、処理する他の行が残ります。この場合、sedコマンドを追加してからの間に最初のシーケンスを挿入することもできます。次に、パターンスペースから最初に表示されるewlineまでパターンスペースを印刷し、残りの部分から始める前に同じ内容を削除します。したがって、全体的に1行の予測が実行され、ジョブスクリプトは常に印刷されます。[ ID_0-9]*[]pcP\nDseddcdc

これは、ファイル全体がストリームで処理されることを意味します。これは`dcsed` の両方が処理されると出力を提供するからです。これにより、入力が質問の例と似ている場合は、同じ方法で200万行を簡単に処理したり、リアルタイムでログファイルを処理したりできます。

おすすめ記事