首页 > 解决方案 > parse .csv data into matrix or 2 dimensional array bash/shell awk

问题描述

I have a coma delimited csv file named 'itrs.csv' which I want to parse into a matrix or 2d array using a script bash or shell

Loads\PostDate,schedule,seta,eeta,2019-11-05,2019-11-06,2019-11-07,2019-11-08
BANAMEX,7,1:18:10,1:23:45,G,G,C,C
EMEA,5,0:21:00,1:01:00,G,G,G,C

I have tried the following:

declare -A matrix
eval matrix=($(awk -f, itrs.csv))
for ((i=0;i<=2;i++))
do
    for ((j=0;j<=$6;j++))
    do
    echo ${matrix[$i,$j]}" " 
    done
    echo
done

but above code is throwing errors. I also would like to know how to check the number of columns and rows while parsing data because csv file size may change.

标签: bashshellmatrixmultidimensional-arrayawk

解决方案


好吧,您可以这样做:创建一个关联数组,遍历行并保持当前行的计数,然后遍历字段并根据请求创建一个具有索引的关联数组。

i=0
declare -A matrix
while IFS=, read -r -a line; do
   for ((j = 0; j < ${#line[@]}; ++j)); do
        matrix[$i,$j]=${line[$j]}
    done
    ((i++))
done < itrs.csv

之后它declare -p matrix会输出:

declare -A matrix=([1,5]="G" [1,4]="G" [1,7]="C" [1,6]="C" [1,1]="7" [1,0]="BANAMEX" [1,3]="1:23:45" [1,2]="1:18:10" [0,4]="2019-11-05" [0,5]="2019-11-06" [0,6]="2019-11-07"[0,7]="2019-11-08" [0,0]="Loads\\PostDate" [0,1]="schedule" [0,2]="seta" [0,3]="eeta" [2,6]="G" [2,7]="C" [2,4]="G"[2,5]="G" [2,2]="0:21:00" [2,3]="1:01:00" [2,0]="EMEA" [2,1]="5" )
  • 请参阅bashfaq 如何逐行(和/或逐字段)读取文件(数据流、变量)?
  • 不要使用eval. eval是邪恶的。eval arr=($(..))除非您知道自己在做什么,否则不要这样做。在您的情况下,使用eval看起来几乎没有意义。
  • 错误来自awk. awk就像awk [options] script [file],你可以awk -F, '{print $0}' itrs.csv,但它没有任何意义。被itrs.csv解析awk为脚本 - 因为它作为awk脚本没有意义,所以该工具会引发错误。
  • 例如,要将仅用逗号分隔的第一行读入 bash 中的数组,您可以IFS=, line=($(head -n1 itrs.csv)). -F,影响如何awk解析文件,而不是如何创建bash数组 - 用于该用途IFS

推荐阅读