次のコードがあります。
sum1=
sum2=
declare -a a
echo $temp | awk '{split($0,a,","); name=a[1] ; for(i=2;i<=4;i++) sum1+=a[i] ; for(i=5;i<=7;i++) sum2+=a[i] }'
このコードは機能しません。ここで temp は文字列型です。
abc,1,2,3,4,5,6
実際にファイルのデータを解析しています。入力ファイルは次のとおりです。
abc,1,2,3,4,5,6
de,3,5,7,8,4,2
xyz,6,5,3,7,8,2
読んで使っています。
while read temp
do
#do something
done < sample.csv
予想される出力は次の形式です。
Name Sum1 Sum2
abc 6 15
de 15 14
xyz 14 17
答え1
この試み:
$ awk -F',' 'BEGIN{OFS="\t";print "Name","Sum1","Sum2"}
{print $1,$2+$3+$4,$5+$6+$7}' sample.csv
Name Sum1 Sum2
abc 6 15
de 15 14
xyz 14 17
Bashループは必要ありませんawk
。この-F
オプションを使用すると、入力フィールド区切り文字(この場合)を定義できるため、明示的に行を,
分割する必要はありません。awk
ファイルは1行ずつ読み取られるため、どちらも読み込む必要はありませんbash
。
このBEGIN{}
ブロックは最初の行を読み取る前に実行され、ヘッダーのみを印刷して設定します。出力区切り文字(OFS
)タブに移動します。フィールドはすでに分離されているので、2-4フィールドと5-7フィールドを合計して各行に印刷するだけです。
答え2
$temp 設定
$temp
まず、変数が正しく設定されていることを確認してください。
$ temp="abc,1,2,3,4,5,6"
$ echo "$temp"
abc,1,2,3,4,5,6
簡単な例
これを行うには、次の方法を使用します。
$ echo "$temp" | tr ',' '\n' | grep -v abc | awk '{sum+=$1};END{print sum}'
21
あなたの模範
あなたの方法に関してチャンクで積み上げられた配列を印刷することを忘れましたEND{...}
。
$ echo "$temp" | awk '{split($0,a,","); name=a[1]
for(i=2;i<=4;i++) sum1+=a[i] ; for(i=5;i<=7;i++) sum2+=a[i] }
END{print sum1; print sum2}'
6
15
後で保存
Awkは呼び出された親シェルに結果を再注入する方法がないため、いくつかのトリックを使用して結果をBashの配列に保存する必要があります。
はい
$ myarr=($(echo "$temp" | awk '{split($0,a,","); name=a[1]
for(i=2;i<=4;i++) sum1+=a[i] ; for(i=5;i<=7;i++) sum2+=a[i] }
END{ print sum1; print sum2}'))
仕組みは次のとおりです。
$ myarr=($(...awk command...))
これにより、値が配列に保存されsum1
ます。sum2
$myarr
$ myarrアレイへのアクセス
次のようにアクセスできます。
$ echo "${myarr[@]}"
6 15
$ echo "${myarr[0]}"
6
$ echo "${myarr[1]}"
15
答え3
吹く
#!/usr/bin/env bash
printf "%-5s\t%s\t%s\n" Name Sum1 Sum2
while IFS=, read -a Arr
do
(( Grp1 = Arr[1] + Arr[2] + Arr[3] ))
(( Grp2 = Arr[4] + Arr[5] + Arr[6] ))
printf "%-5s\t%d\t%d\n" ${Arr[0]} $Grp1 $Grp2
done < input.txt
出力
root@ubuntu:~# bash parse.sh
Name Sum1 Sum2
abc 6 15
de 15 14
xyz 14 17
配列要素の算術ヒントを提供した@1_CRに感謝します。