grep 使用数组值并使其更快

grep 使用数组值并使其更快

array[1] 是从 30k 行 CSV 中提取的字符串:示例:

samsung black 2014

我需要将这些行与数组 (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')"

另一件事是...如何更快地完成 $file_in 是一个 30k 行的 CSV?

答案1

您可以将 grep 与文件模式选项 (-f) 一起使用

例子:

$ 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

您的脚本中有两个错误:

  • grep 尝试匹配字符串,$itemToFind因为您将其放在单引号之间'。请改用双引号。

  • 您正在使用索引为 1 的数组,同时help read告诉它从零开始。

这应该给出:

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[0]} | grep -o "$itemToFind")
       if [ -n "$itemFound" ] 
       then 
          echo $itemFound 
          # so end to search in case the item is found
          break
       fi
    done
done < $file_in

编辑:

如果你想让它更快,你可以使用扩展正则表达式:

grep -E 'apple|sony|samsung' $file_in

如果您只想显示品牌:

grep -E 'apple|sony|samsung' $file_in | awk '{print $1}'

相关内容