固定されていない列数を使用した行ごとの算術計算

固定されていない列数を使用した行ごとの算術計算

固定されていない列番号を含む入力ファイルがあり、それに対して算術計算を実行しようとしています。

input.txt
ID1    4651455    234     4651765    392     4652423      470
ID2    16181020   176    16184958    869     16185889     347    16187777     231

入力ファイルには、列内でID常に一意の(繰り返しない)タブ区切りフィールドがあります。$1すべての行に同じ数の列があるわけではありません。

私が達成したいのは、次のようにタブ区切りのファイルです。

 output1.txt
 ID1     76    266   
 ID2     3762   62   1541  

デフォルトでは、元のファイルを印刷して$1から、ファイルの2番目の偶数列()から始めて最初の2つの列( - - )の$4値を減算し、入力ファイル内のすべての偶数列に対して同じ操作を実行します(例: - - ; - - ; ...).私が知っている限り、これはを介して行うことができますが、私のファイルに行ごとに固定数の列がある場合にのみこれを処理する方法を知っています。$4$3$2$6$5$4$8$7$6awk print

私の要件を満たすより理想的な出力は次のとおりです。

output2.txt
ID1    234    76    392    266   470
ID2    176   3762   869    62    347   1541  231

デフォルトでは、元のファイルを印刷$1し、入力ファイルの奇数列をoutput1.txt

答え1

$ awk -v OFS='\t' -f script.awk file
ID1     76      266
ID2     3762    62      1541

script.awkどこ

{ printf("%s", $1) }
{ for (i=4; i<=NF; i+=2) { printf("%s%d", OFS, $i - $(i-1) - $(i-2)) } }
{ printf("%s", RS) }

ファイルの各入力行に対して、すべてのブロックが実行されます。

最初のブロックはIDを出力します。

2番目のブロックは、ユーザーが説明したようにフィールドを繰り返しOFS(出力フィールド区切り記号、コマンドラインのタブに設定)、区切りデータを出力します。

最後のブロックは、デフォルトRSで改行であるレコード区切り文字を出力します。

または、

BEGIN { OFS = "\t" }
{ printf("%s", $1) }
{ for (i=4; i<=NF; i+=2) { printf("%s%d", OFS, $i - $(i-1) - $(i-2)) } }
{ printf("%s", RS) }

正しい必要性を取り除きます-v OFS='\t'

「一行」で:

$ awk 'BEGIN { OFS = "\t" }
{ printf("%s", $1) }
{ for (i=4; i<=NF; i+=2) { printf("%s%d", OFS, $i - $(i-1) - $(i-2)) } }
{ printf("%s", RS) }' file

拡張質問の場合:

{ printf("%s", $1) }
{ for (i=4; i<=NF; i+=2) { printf("%s%d%s%d", OFS, $(i-1), OFS, $i - $(i-1) - $(i-2)) } }
{ printf("%s%d%s%s", OFS, $NF, OFS, RS) }

これにより、元のファイルから直接次のものが生成されます。

ID1     234     76      392     266     470
ID2     176     3762    869     62      347     1541    231

答え2

アッ解決策:

awk '{ r=$1; for(i=4;i<=NF;i+=2) r=r"\t"$i-$(i-1)-$(i-2); printf "%s\n",r }' OFS='\t' file
  • r=$1- 最初のフィールドキャプチャ

  • for(i=4;i<=NF;i+=2)- 繰り返しでもフィールド

  • $i-$(i-1)-$(i-2)- 必要な減算を実行します。


出力:

ID1 76  266
ID2 3762    62  1541

関連情報