CSVファイルから値を取得し、それに関連する他の値を取得する方法は?

CSVファイルから値を取得し、それに関連する他の値を取得する方法は?

myfile.csv

445,aLabel
446,anotherLabel
447,aThirdLabel

Bashスクリプトでmyfile.csvを検索して「anotherLabel」(大文字と小文字を区別しない)があるかどうかを検索し、値446を取得したいと思います。また、「anotherLabel」が存在しない場合は、最後に追加して前の行のラベルを1ずつ増やしたいと思います。

私は次の文から始めますif

if grep -Fiq anotherLabel myfile.csv; then
    #get the value of field 1 (446 in this example) and store it in a variable
else
    #increment the last value of field 1 present in the file and store it in a variable
    #and append "448,anotherLabel" to myfile.csv
fi

ファイルにタグがあるかどうかを確認するためにgrepを使用することがこの問題を解決する最善の方法であるか、sedまたはawkを使用するより簡単な方法があるかどうかはわかりません。

答え1

この試み:

 awk -F',' '{ if ($2 == "anotherLabel") { print $1 } }' myfile.csv

答え2

使用greptail:

search="anotherLabel"
file=myfile.csv

if value=$(grep -Pio -m1 "^[0-9]+(?=,$search$)" "$file"); then
    echo "do something with $value"
elif lastvalue=$(tail -n1 "$file" | grep -o '^[0-9]\+'); then
    # append lastvalue + 1 and search string
    echo "$((++lastvalue)),$search" >> "$file"
else
    # handle error
    echo "error. no integer value in last line of \"$file\" found." >&2
fi

最初のオプションはgrep次のオプションを使用します。

  • -P肯定的な予測を使用するには、Perl準拠正規表現(PCRE)を有効にします(以下を参照)。
  • -iパターンで大文字と小文字を無視
  • -o行の一致部分のみを印刷
  • -m1最初のゲーム後に停止

最初の正規表現は、^[0-9]+(?=,$search$)順方向予測を使用して、(?=pattern)次の数字,とカンマなしで検索文字列を一致させ、検索文字列は一致自体の一部です。オプションと組み合わせると、一致する-o部品(番号)のみが印刷されます。

答え3

純粋なbashでこれを行うには、次のようにします。

file="myfile.csv"
seek="anotherLabel"
while IFS=, read id label; do
    if [[ $label == "$seek" ]]; then
        myid=$id
        break
    fi
    lastid=$id
done < "$file"
if [[ -z $myid ]]; then
    myid=$((lastid + 1))
    echo "$myid,$seek" >> "$file"
fi
echo "$seek id is: $myid"

答え4

次のawkコードは要件を満たしています。

#!/bin/bash

filetosearch=myfile.csv
searchString=${1:-anotherLabel}

awk -F',' -v pat="$searchString" '
BEGIN{patl=tolower(pat);flag=0};
{prev=$1}(tolower($0)==patl){flag=1;exit}
END{
     if(flag){
          print prev
             }else{
          printf("%s%s%s\n", prev+1,FS,pat) >> ARGV[1]    # use ARGIND in gawk.
          print prev+1
             }
   }' "${filetosearch}"

"${searchString}"行全体に正確に一致する文字列(より緩やかに一致するtolower($0)==patlように変更されたtolower($0)~patl)を検索し、その文字列が見つかったインデックスを報告します。文字列が一致しない場合は、ファイルの最後のインデックスより1が大きいインデックスとして使用されるファイルに追加(追加)されます。

例:

$ ./script aLabel
445

$ ./script anotherLabel
446

$ ./script MissingLabel
450

$ cat myfile.csv
445,aLabel
446,anotherLabel
447,aThirdLabel
448,dhdhdhdhdhd
449,anotherLabel4646
450,MissingLabel

関連情報