并行迭代多个bash数组更优雅

兴奋剂

我正在研究一个脚本,该脚本会咀嚼一些从CSV文件吸收的数据。我已经将数据读入几个数组中(文件中的每一列一个);现在,我需要按顺序实际处理所有数据。

目前,我正在这样做:

# Read in the data:
declare -a DATACOL1 DATACOL2 RAWDATA
RAWDATA=($( sed '1d' /path/to/data.csv )) # Remove the header line
for line in ${RAWDATA[@]}; do
   declare -a LINEDATA LINE
   LINE=$( echo "$line" | sed 's/,/ /g' )
   for field in LINE; do
       LINEDATA+=("${field}")
   done
   DATACOL1+=(${LINEDATA[0]})
   DATACOL2+=(${LINEDATA[1]})
done


# Work on the data:
for i in $( seq 0 $[${#DATACOL1[@]}-1}; do
   stuff and things with ${DATACOL1[i]} and ${DATACOL2[i]}
done

我的(很可能是相互关联的)问题是双重的:

  • 有没有比在数据上for i in $( seq 0 $[${#DATACOL1[@]}-1}进行迭代更优雅的方式来以后处理数据了?它可以工作,但是很难看。

  • 有没有更优雅的方式来吸收CSV数据?

这是在bash 3上,因此我没有关联数组。

格伦·杰克曼

我会写:

mapfile -t rawdata < <(sed 1d /path/to/data.csv)
datacol1=()
datacol2=()

for line in "${rawdata[@]}"; do
    IFS=, read -ra fields <<< "$line"
    datacol1+=( "${fields[0]}" )
    datacol2+=( "${fields[1]}" )
done

for ((i=0; i < "${#datacol1[@]}"; i++)); do
    stuff with "${datacol1[i]}" and "${datacol2[i]}"
done
  • 用于mapfile将文件的行读入数组
  • 使用IFSread从一行中读取逗号分隔的字段
    • 将用引号引起来的字符串中的逗号分隔:使用真正的CSV解析器
  • 使用类似C的形式for以避免调用seq

当然,您不需要第二个循环或datacol *变量

for line in "${rawdata[@]}"; do
    IFS=, read -a fields <<< "$line"
    stuff with "${fields[0]}" and "${fields[1]}"
done

在bash 3上,您将没有mapfile,因此请使用while循环

datacol1=()
datacol2=()
while IFS=, read -ra fields; do
    datacol1+=("${fields[0]}")
    datacol2+=("${fields[1]}")
done < <(sed 1d /path/to/data.csv)

本文收集自互联网,转载请注明来源。

如有侵权,请联系 [email protected] 删除。

编辑于
0

我来说两句

0 条评论
登录 后参与评论

相关文章