使用数组元素作为我想从文件中读取的变量的名称

时间:2018-06-06 21:36:39

标签: arrays bash list csv parsing

我知道读取.csv文件只需使用此循环在bash中完成:

#!/bin/bash
INPUT=data.cvs
OLDIFS=$IFS
IFS=,
[ ! -f $INPUT ] && { echo "$INPUT file not found"; exit 99; }
while read flname dob ssn tel status
do
    echo "Name : $flname"
    echo "DOB : $dob"
    echo "SSN : $ssn"
    echo "Telephone : $tel"
    echo "Status : $status"
done < $INPUT
IFS=$OLDIFS

但是我想稍微修改一下 - 我想让程序员在bash文件中定义列。 例如:

declare -a columns=("Name", "Surname", "ID", "Gender")
while read columns
    do
        //now echo everything that has been read
done < $INPUT

所以我想指定应该用作读取带有数组的CSV数据的容器的变量列表,然后在while体内访问该数组。
有办法吗?

2 个答案:

答案 0 :(得分:1)

此解决方案的关键是下面while声明之前的评论。 read是内置的,但它仍然是一个命令,并且在执行命令之前shell会扩展命令参数。扩展${columns[@]}后,命令变为

read Name Surname ID Gender

示例:

# Don't use commas in between array values (since they become part of the value)
# Values not quoted because valid names don't need quotes, and these
# value must be valid names
declare -a columns=(Name Surname ID Gender)

然后,我们可以尝试:

# Read is a command. Arguments are expanded.
# The quotes are unnecessary but it's hard to break habits :)
while read "${columns[@]}"; do
  echo Name is "$Name"
  # etc
done <<< "John Doe 27 M"

输出:

Name is John

即使在没有数组的shell中,这种方法也可以工作;列名可以只是一个空格分隔列表。 (示例在破折号,Posix shell中运行)

$ columns="Name Surname ID Gender"
$ # Here it is vital that $columns not be quoted; we rely on word-splitting
$ while read $columns; do 
> echo Name is $Name
> done 
John Doe 27 M
Name is John

...

答案 1 :(得分:0)

将该行读入数组,然后遍历该数组并创建一个使用列名的关联数组。

while read -r line
do
    vals=($line)
    declare -A colmap
    i=0
    for col in ${columns[@]}
    do
        colmap[col]=${vals[$i]}
        let i=i+1
    done
    # do stuff with colmap here
    # ...
    unset colmap # Clear colmap before next iteration
done < $INPUT