CSV 文件 + 在 bash 脚本中设置 CSV 参数和值

CSV 文件 + 在 bash 脚本中设置 CSV 参数和值

我有以下 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循环查看第一行中的每个字段并将值(状态名称)分配给数组snsn[1]=Alabama, sn[2]=Alaska, ...)。
  • 第二个for循环查看第二行中的每个(逗号分隔)字段,并将其与相应的州名称(来自第一行)和 配对=,如上所示。
  • 然后我们exitawk不需要读取文件的其余部分。

所以

评估$(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;退出}'状态

将捕获该输出并将其解释为一系列命令。完毕。


如果您决定使用 shell 循环和命令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

或者您可以明确列出州名称,就像您在示例/尝试 ( ) 中所做的那样。但是,当数据已经在文件中时,为什么要在代码中复制数据呢?你可以消除变量并做for var in Alabama Alaska Arizona Arkansas …values

eval $state_name=$(sed -n '2p;2q' states | cut -d, -f$counter)

在循环中,但这需要读取states文件 50 次而不是一次。 (或者如果你算一下语句的话,是 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 ...

  • 第二个 sed 命令对第二行执行相同的操作(在您的问题中似乎您只需要第二行的值):1000 1001 1002 1002 ...

  • read -r将第一个列表分配给第二个列表。

您可以使用以下命令测试这些值之后echo

echo $Alabama
1000
echo $Alaska
1 0 0 1
echo $Georgia
1008

相关内容