我正在编写一个脚本,该脚本会处理从 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 上,所以我没有关联数组。
答案1
我会写:
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
将文件的行读入数组 - 使用
IFS
和read
从一行中读取逗号分隔的字段- 将用带引号的字符串中的任何逗号分隔:使用真正的 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)