ほぼ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]
\n
p
[string]
x
dc
したがって、現在の行が最後の行の場合は、sed
まず$!N
現在の行に追加の行を追加します。 2行目はstdoutに文字列を挿入します。これは精度を3に設定するコマンドです。!
$
i
3k
dc
その後、交換しようとしています。
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行を次のように変更します。sed
sed
[ 10 ID_1 ]P10d20+/p[ 20 ID_2]pc
...dc
次に、その入力を次のように処理します。
[ 10 ID_1 ]
- 角かっこの間の文字列をスタックの一番上にスライドさせます。(これを行うと、すでにスタック内のすべてのアイテムが1つ下にプッシュされます。)P
P
- 後ろに並んでいないスタックの上部を印刷して\n
ポップします。(これを行うと、下のスタックのすべての値が1ずつ増加します。)10
- 数字10をスタックの一番上にスライドさせます。d
d
- スタックの上部をコピーします。20
- 数字20をスタックの一番上にスライドさせます。+
- スタックの上部に2cdを追加し、スタックの上部に2cdを追加します。(2つを同時に爆発させる)そして結果をスタックの一番上にスライドさせます。/
- スタックの上から2cdを分割します。(今私たちはd
コピーします10
)スタックの上から(私たちの10 20 +
結果) (2つを同時に爆発させる)そして結果をスタックの一番上にスライドさせます。p
p
- スタックの上部を印刷します。(揚げずに)その後に行が表示されます\n
。[ 20 ID_2]
- 文字列をスタックの一番上にスライドさせます。p
p
- スタックの上部を印刷します。(もう一度言うが爆発しないでください)その後は\n
Ewlineが続くc
c
- スタックを理解する
したがって、dc
以下を印刷してください。
10 ID1_1 .333
20 ID1_2
ただし、sed
すでに説明したように、成功した一致がなく、パターンスペースが変更された場合、処理する他の行が残ります。この場合、sed
コマンドを追加してからの間に最初のシーケンスを挿入することもできます。次に、パターンスペースから最初に表示されるewlineまでパターンスペースを印刷し、残りの部分から始める前に同じ内容を削除します。したがって、全体的に1行の予測が実行され、ジョブスクリプトは常に印刷されます。[ ID_0-9]*
[
]
pc
P
\n
D
sed
dc
dc
これは、ファイル全体がストリームで処理されることを意味します。これは`dc
とsed
` の両方が処理されると出力を提供するからです。これにより、入力が質問の例と似ている場合は、同じ方法で200万行を簡単に処理したり、リアルタイムでログファイルを処理したりできます。