固定されていない列番号を含む入力ファイルがあり、それに対して算術計算を実行しようとしています。
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
$6
awk 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