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}'