3つの列(区切り記号はカンマ)で構成されるファイルがあります。最初の列にはIDが含まれ、2番目と3番目の列には合計したい値が含まれています。合計は、出力のファイルに4番目の列として追加する必要があります。
ただし、場合によっては、3番目の列が空になることがあります(入力ファイルの2行目など)。この場合、合計に関連する列は空でなければなりません。ただし、フィールドが明示的に表示されている場合は、0
合計は通常どおりに計算する必要があります(たとえば、入力ファイルの4行目)。
- 入力.txt
2309,-0.3,0.2 2311,1.2, 2312,0,-1 2315,2.2,0
- 希望の出力:
2309,-0.3,0.2,-0.1 2311,1.2,, 2312,0,-1,-1 2315,2.2,0,2.2
以前は同様の議論を見たことがありますが、2番目と3番目の列の間で合計を計算する必要があることを指定する方法と、3番目の列が空の行の合計をスキップする方法を知りません。以下のスクリプトは、同じ行(またID??)に含まれるすべての値を合計するようになっていますが、どういうわけか変更できますか?それとも他のより速い方法を提案してもらえますか?
NF++; $NF=sum
awk -v OFS=, -F, 'NR>1{sum=0; for(i=1; i<=NF; i++) sum += $i; NF++; $NF=sum } 1'
答え1
$ awk 'BEGIN{FS=OFS=","} {print $0, ($3=="" ? "" : $2+$3)}' input.txt
2309,-0.3,0.2,-0.1
2311,1.2,,
2312,0,-1,-1
2315,2.2,0,2.2
答え2
$ cat dst
2309,-0.3,0.2,-0.1
2311,1.2,,
2312,0,-1,-1
2315,2.2,0,2.2
$ cat awkscript
#!/bin/sh
awk -F, '
{
if ($3 == "") $0 = $0 ","
else $0 = $0 "," $2+$3
print $0
}
' $1 >$2
$ ./awkscript src dst
$ cat dst
2309,-0.3,0.2,-0.1
2311,1.2,,
2312,0,-1,-1
2315,2.2,0,2.2
答え3
これは次の手順を使用してawk
可能です。
awk 'BEGIN{FS=OFS=","} {sum=0; for (i=2;i<=NF;i++) {if ($i=="") {sum=""; break}; sum+=$i}; $(NF+1)=sum}1' input.txt
これは
- 入力フィールドと出力フィールドの区切り記号(
FS
およびOFS
)を次のように設定します。,
- 各行に対して
sum
変数をリセットし0
、フィールド2で始まるすべてのフィールドを合計します。ただし、フィールドが明示的に空の場合($i==""
)は、合計ループから外れて空のsum
文字列に設定されます。 sum
次に、新しい追加フィールドを(実際の合計または空の文字列)値に設定します。- 最後に、すべての修正を含む現在の行を印刷します。これは
1
ルールブロックの外で「さまよう」と思われます。awk
ルールブロックの外側に「true」と評価されるブール条件がある場合、現在の行が印刷されます。
入力例の場合、出力は次のようになります。
2309,-0.3,0.2,-0.1
2311,1.2,,
2312,0,-1,-1
2315,2.2,0,2.2
答え4
mlr
代わりにMiller()を使用してくださいawk
。
$ mlr --csv -N put 'is_not_empty($3) { $4 = $2 + $3 }' then unsparsify file
2309,-0.3,0.2,-0.100000
2311,1.2,,
2312,0,-1,-1
2315,2.2,0,2.200000
これにより、null以外の3番目のフィールドを持つすべてのレコードに4番目のフィールドが作成されます。unsparsify
これにより、前のステップでフィールドが生成されなかったすべてのレコードに欠落している4番目のフィールドが生成されます。