awkを使って最初の行から行を引く方法は?

awkを使って最初の行から行を引く方法は?

私のデータファイルは次のとおりです。

10 -0.314690785295
20 -0.251967909317
30 -0.215271387106
40 -0.189228416217

希望の出力は次のとおりです。

10 -0.0627229
20 -0.0994193
30 -0.1254623

答え1

  awk 'BEGIN {first_row = 0; col_val=""}{ if (first_row == 0) {first_row = $2; col_val=$1} else {print col_val " " first_row - $2; col_val=$1}}'

以下はコマンドラインの出力です。

 $ echo "10 -0.314690785295
 20 -0.251967909317
 30 -0.215271387106
 40 -0.189228416217" | awk 'BEGIN {first_row = 0; col_val=""}{ if (first_row == 0) {first_row = $2; col_val=$1} else {print col_val " " first_row - $2; col_val=$1}}'
 10 -0.0627229
 20 -0.0994194
 30 -0.125462

いいですね。それでは、なぜこれが起こるのかを説明しましょう。

BEGIN句は、開始前に初期化として実行されるコードセクションを定義します。この位置で、残りのロジック全体で追跡する2つの変数を初期化します。

プログラムの主要部分にある{}の2番目のセットにあります。入力の各行に対して実行されるロジックを定義します(特定の行でのみ実行されるようにパターンを追加することもできますが、これはこの回答の範囲外です)。

このロジックは first_row 値が設定されているかどうかをテストします。それ以外の場合、これは入力の最初の行です。 first_row値をその行の2番目の文字列である$ 2に初期化し、必要な値と一致するように最初の列である$ 1の文字列もコピーする必要があります。出力、値をcol_valにコピーします。

それ以外の場合は、入力の他のすべての行に対して col_value を 1 つの空白で印刷し、現在の行の 2 番目の位置 $2 の値から first_row を引いた結果を印刷するので、 first_row - $2 になります。次に、入力の最初の列で新しい文字列値をcol_valにコピーします。

初めて私はあなたに本当に必要なものが何であるか理解していません:).. ここであなたがしたいことを行うためのawkスクリプトがあります。

 awk '{ if (NR == 1) { for (i = 1; i <= NF; i++){ first_row[i] = $i} } else { for (i = 1; i <= NF; i++){ printf "%s ", first_row[i] - $i }; printf "\n"}}'

出力は次のとおりです。最初の列で予想したものとは若干異なります。進行状況を表示するために別の列を追加しました。

 echo "10 -0.314690785295 18
 20 -0.251967909317 12
 30 -0.215271387106 35
 40 -0.189228416217 44" | awk '{ if (NR == 1) { for (i = 1; i <= NF; i++){first_row[i] = $i} } else { for (i = 1; i <= NF; i++){ printf "%s ", first_row[i] - $i }; printf "\n"}}'
 -10 -0.0627229 6 
 -20 -0.0994194 -17 
 -30 -0.125462 -26 

関連情報