Bash

posix bash,如何讀取 csv 文件並忽略某些列?

  • February 16, 2022

POSIX shell 上,沒有可用的Pythonawk(所以不要告訴我我應該使用“真正的”程式語言)我必須遍歷csv文件。

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"

不知何故,這起到了作用,但標題行也被處理了。

另一個問題是沒有引用欄位’ rec_version ‘、’ rec_origin ‘和’ rec_modification ‘。

如何忽略它們?

因為我也試過:

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

那麼,您對此有何看法?

問候。

在您的第一次嘗試中只有<()非 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

引用自:https://unix.stackexchange.com/questions/690885