posix bash,如何读取csv文件并忽略某些列?

posix bash,如何读取csv文件并忽略某些列?

在一个POSIX外壳,没有Python和不awk可用(所以不要费心告诉我应该使用“真正的”编程语言)我必须循环数据集文件。

https://datacadamia.com/lang/bash/read

我最初的猜测是:

while IFS=";" read -r rec_name rec_version rec_license rec_origin rec_modification rec_newlicense
do
    if [ "$name" = "$rec_name" ]; then
        # if [ "$version" = "$rec_version" ]; then
            if [ "$license" = "$rec_license" ]; then
                license="$rec_newlicense"
            fi
        # fi
    fi
done < <(tail -n +2 "${output_file%%.*}.csv")

但最后一行不是“POSIX“ 符合要求。所以我尝试了:

while IFS=";" read -r rec_name rec_version rec_license rec_origin rec_modification rec_newlicense
do
    if [ "$name" = "$rec_name" ]; then
        # if [ "$version" = "$rec_version" ]; then
            if [ "$license" = "$rec_license" ]; then
                license="$rec_newlicense"
            fi
        # fi
    fi
done < "${output_file%%.*}.csv"

不知何故,这成功了,但标题行也被处理了。

另一个问题是字段 '记录版本','记录源' 和 '记录修改' 没有被引用。

如何忽略他们?

因为我也尝试过:

while IFS=";" read -r -a rec
do
    if [ "$name" = "${rec[0]}" ]; then
        # if [ "$version" = "${rec[1]}" ]; then
            if [ "$license" = "${rec[2]}" ]; then
                license="${rec[5]}"
            fi
        # fi
    fi
done < "${output_file%%.*}.csv"

但后来我得到:

read: line 93: illegal option -a

那么,你对此有何看法?

问候。

答案1

<()第一次尝试时只是非 POSIX,所以只需使用普通管道即可:

tail -n +2 "${output_file%%.*}.csv" | 
  while IFS=";" read -r rec_name rec_version rec_license rec_origin rec_modification rec_newlicense
  do
    if [ "$name" = "$rec_name" ]; then
        if [ "$license" = "$rec_license" ]; then
            license="$rec_newlicense"
        fi
    fi
  done

但这似乎有点复杂。我不能确定,因为你没有显示你正在解析的数据,但我怀疑你可以这样做:

tail -n +2 "${output_file%%.*}.csv" | 
  while IFS=";" read -r rec_name rec_version rec_license rec_origin rec_modification rec_newlicense
  do
    if [ "$name" = "$rec_name" ] && [ "$license" = "$rec_license" ] 
    then
        license="$rec_newlicense"
    fi
  done

至于忽略未使用的术语,恐怕您无法对中间的术语执行此操作。您可以轻松地采用前 N 项并忽略其余项:

while read -r var1 var2 rest; do ... done

这将读取前 2 个变量并将该行的其余部分保存为rest.不幸的是,如果您需要使用最后一个,则需要捕获所有这些。或者,在传递到 shell 之前删除它们:

tail -n +2 "${output_file%%.*}.csv" | 
    cut -d';' -f1,3,6 | 
        while IFS=";" read -r rec_name rec_license  rec_newlicense
        do 
          if [ "$name" = "$rec_name" ] && [ "$license" = "$rec_license" ] 
          then
              license="$rec_newlicense"
          fi
        done

相关内容