web-dev-qa-db-ja.com

配列値を使用してgrepを実行し、高速化します

array [1]は、30k行のCSVから取得した文字列です。例:

samsung black 2014

これらの行を、配列に含まれる値の1つ(arrayItems)と一致させる必要があります。

arrayItemsには、次のような221個の値が含まれています。

Apple
sony
samsung

実際のスクリプト:

while IFS=$';' read -r -a array
do
    mapfile -t arrayItems < $itemsFile
    ## now loop through the above array
    for itemToFind in "${arrayItems[@]}"
    do
       itemFound=""
       itemFound="$(echo ${array[1]} | grep -o '^$itemToFind')"
       if [ -n "$itemFound" ] 
       then 
          echo $itemFound 
          # so end to search in case the item is found
          break
       fi
    done
   # here I do something with ${array[2]}, ${array[4]} line by line and so on, 
   # so I can't match the whole file $file_in at once but online line by line.
done < $file_in

問題は、grepが一致しないことです。

しかし、次のように$ itemToFindをハードコーディングしようとすると機能します:

itemFound="$(echo ${array[1]} | grep -o '^samsung')"

もう1つは、$ file_inが3万行のCSVであるため、どのように高速化するかです。

1
Kintaro

ファイルパターンオプション(-f)でgrepを使用できます

例:

$ echo -e "Apple\nsony\nsamsung" > file_pattern
$ grep -f file_pattern your.csv

編集:あなたの新しい制約に応えて:

sed 's/^/\^/g' $itemsFile > /tmp/pattern_file
while IFS=$';' read -r -a array
do
    echo ${array[1]} | grep -q -f /tmp/pattern_file.txt
    if [ $? -eq 0 ]; then 
        # here I do something with ${array[2]}, ${array[4]} line by line and so on, 
        # so I can't match the whole file $file_in at once but online line by line.
    fi
done < $file_in
2
apapillon