次のCSVファイルがあります。
Alabama,Alaska,Arizona,Arkansas,California,Colorado,Connecticut,Delaware,Florida,Georgia,Hawaii,Idaho,Illinois,Indiana,Iowa
1000,"1 0 0 1",1002,1002,1003,1004,1005,"1 0 0 6",1007,1008,1009,1010,1011,1012,1013
100,101,102,102,103,104,105,"1 0 6 2",107,108,109,110,111,112,113
10001,10011,10021,10021,10031,10041,10051,10061,10071,10081,10091,10101,10111,10121,10131
.
.
.
.
私の目標は、bashスクリプトでCSVパラメータ(CSVのすべての状態)とその値を設定することです。
例えば
#!/bin/bash
Alabama=1000
.
.
.
Iowa=1013
したがって、私のbashスクリプトから各パラメータを読み取ることができます。
はい
echo $Alabama
1000
まず、パラメータをその値に設定するために、次の(誤った)コードを書いてみました。
#!/bin/bash
counter=1
for CSV_COLUMN in Alabama Alaska Arizona Arkansas California Colorado Connecticut Delaware Florida Georgia Hawaii Idaho Illinois Indiana Iowa
do
export $CSV_COLUMN=` echo $CSV_LINE | cut -d',' -f$counter `
counter=$counter+1
done
テストは(bashスクリプトから)
echo $Alabama
1000
私のアイデアを実装するには、コードをどのように変更する必要がありますか?
答え1
注文する
awk -F, 'NR==1 { for (i=1; i<=NF; i++) sn[i]=$i }
NR==2 { for (i=1; i<=NF; i++) print sn[i] "=" $i; exit }' states
states
出力するファイルはどこにありますか?
Alabama=1000
Alaska="1 0 0 1"
Arizona=1002
Arkansas=1002
California=1003
Colorado=1004
Connecticut=1005
Delaware="1 0 0 6"
Florida=1007
Georgia=1008
Hawaii=1009
Idaho=1010
Illinois=1011
Indiana=1012
Iowa=1013
-F,
awk
フィールド区切り記号をに設定します,
。NR==1
「最初のレコード(行)でのみ次の操作を実行してください」を意味NR==2
します。- (最初の項目)は
for
最初の行の各フィールドを繰り返し、値(状態名)を配列に割り当てますsn
:sn[1]=Alabama
、、、sn[2]=Alaska
...)。 - 2番目のループは2番目の行の各(カンマで区切られた)フィールドを見て、上記のように対応
for
するメイン名(最初の行の)とペアになります。=
- これにより、ファイルの残りの部分を読む必要はありません
exit
。awk
だから
評価$(awk -F, 'NR==1 { for (i=1; i<=NF; i++) sn[i]=$i } NR==2 { for (i=1; i<=NF; i++) print sn[i] "= $i;exit}' ステータス)
この出力はキャプチャされ、一連のコマンドとして解釈されます。完璧。
シェルループとコマンドを使用することにした場合は、cut
次の点を考慮してください。
values=$(sed -n '2p;2q' states)
counter=1
for state_name in $(sed 's/,/ /g;1q' states)
do
eval $state_name=$(echo "$values" | cut -d, -f$counter)
counter=$((counter+1))
done
または、example/try() で行ったように、状態名を明示的にリストすることもできます。しかし、データはすでにファイルにありますが、コードからデータをコピーするのはなぜですか?変数を削除して次のことができます。for var in Alabama Alaska Arizona Arkansas …
values
eval $state_name=$(sed -n '2p;2q' states | cut -d, -f$counter)
ただし、これを行うには、states
ファイルを1回ではなく50回読み取る必要があります。 (またはステートメントを数えてみると、2回ではなく51回になりますfor state_name in $(sed 's/,/ /g;1q' states)
。)
答え2
次の行を使用してください。
read `sed -e 's/,/ /g' -e '1q;d' file` < <(sed -e 's/\ /\\\ /g' -e 's/"//g' -e 's/,/ /g' -e '2q;d' file)
説明する:
最初の
sed
コマンドはファイルの最初の行だけを印刷し、コンマ(,
)を空白に置き換えます。Alabama Alaska Arizona Arkansas California ...
2番目のsedコマンドは2行目に対して同じことを行います(質問では2行目の値のみが必要になるようです)
1000 1001 1002 1002 ...
。read -r
最初のリストを2番目のリストに割り当てます。
後で、次のコマンドを使用してこれらの値をテストできますecho
。
echo $Alabama
1000
echo $Alaska
1 0 0 1
echo $Georgia
1008