awkを使用して最初の行の列値を減算するには?

awkを使用して最初の行の列値を減算するには?

入力ファイルは「id number1 number2 count」行で、number1とnumber2の両方が昇順です。

Barcode000000 48521 1855 0
Barcode000001 48621 1855 0
Barcode000002 48721 1855 1
Barcode000003 48821 1855 0
Barcode000004 48921 1955 20
Barcode000005 49021 1955 0

今私はそれを使用しますawk -v bin=100 '{print ($2-48521)/bin" "($3-1855)/bin" "$4}'

入力ファイルの最初の行で合計をどのように設定しますか485211855

答え1

変数に保存して、その変数が何であるかを覚えてから、その変数を使用して新しいフィールドを計算します。特殊変数が1なので、最初のレコード(行)を見ていることがわかりますNR。以下のコードは、数値をasumに保存しますb

$ awk -v bin=100 'NR == 1 { a = $2; b = $3 } { $2 = ($2 - a)/bin; $3 = ($3 - b)/bin; print }' file
Barcode000000 0 0 0
Barcode000001 1 0 0
Barcode000002 2 0 1
Barcode000003 3 0 0
Barcode000004 4 1 20
Barcode000005 5 1 0

テスト前のブロックはNR == 1最初のレコードに対してのみ実行され、2番目のブロックは条件なしですべてのレコードに対して実行されます。

または、最初のフィールドがない場合(これはコードの出力結果に近いです):

$ awk -v bin=100 'NR == 1 { a = $2; b = $3 } { print ($2 - a)/bin, ($3 - b)/bin, $4 }' file
0 0 0
1 0 0
2 0 1
3 0 0
4 1 20
5 1 0

デフォルトの出力フィールド区切り文字は単一のスペースであるため、コンマを使用して出力レコードのフィールドを区切る場合はスペースを挿入する必要はありません。出力区切り記号は、特殊変数の値を設定することで変更できますOFS

答え2

awkを使用してください。

$ awk -v bin=100 'NR==1{split($0,a)} {for (i=2;i<=3;i++) $i=($i-a[i])/100} 1' file
Barcode000000 0 0 0
Barcode000001 1 0 0
Barcode000002 2 0 1
Barcode000003 3 0 0
Barcode000004 4 1 20
Barcode000005 5 1 0

または、特定のフィールドの小さなセットのみを印刷したい場合:

$ awk -v bin=100 'NR==1{split($0,a)} {for (i=2;i<=3;i++) $i=($i-a[i])/100; print $2, $3, $4}' file
0 0 0
1 0 0
2 0 1
3 0 0
4 1 20
5 1 0

または、フィールドが多いが最初のフィールドを印刷したくない場合:

$ awk -v bin=100 'NR==1{split($0,a)} {for (i=2;i<=3;i++) $i=($i-a[i])/100; $1=""; sub(OFS,"")} 1' file
0 0 0
1 0 0
2 0 1
3 0 0
4 1 20
5 1 0

答え3

使用ミラー( mlr):

$ bin=100
$ mlr --nidx step -a from-first -f 2,3 then put '$2 = ${2_from_first} / '$bin' ; $3 = ${3_from_first}/ '$bin'; unset  ${2_from_first}, ${3_from_first}' file
Barcode000000 0 0 0
Barcode000001 1 0 0
Barcode000002 2 0 1
Barcode000003 3 0 0
Barcode000004 4 1 20
Barcode000005 5 1 0

または、最初のフィールドはありません。

$ bin=100
$ mlr --nidx step -a from-first -f 2,3 then put '$2 = ${2_from_first} / '$bin' ; $3 = ${3_from_first}/ '$bin'; unset $1, ${2_from_first}, ${3_from_first}' file
0 0 0
1 0 0
2 0 1
3 0 0
4 1 20
5 1 0

stepサブコマンドについてミラー文書:

計算は前/後に記録された値によって異なり、オプションでカテゴリ別にグループ化されます。

from-first は、フィールドと最初のレコードの差を計算します。

関連情報