![배열 값으로 grep하여 더 빠르게 만듭니다.](https://linux55.com/image/142856/%EB%B0%B0%EC%97%B4%20%EA%B0%92%EC%9C%BC%EB%A1%9C%20grep%ED%95%98%EC%97%AC%20%EB%8D%94%20%EB%B9%A0%EB%A5%B4%EA%B2%8C%20%EB%A7%8C%EB%93%AD%EB%8B%88%EB%8B%A4..png)
array[1]은 30,000행 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이 30,000행의 CSV인 경우 어떻게 하면 더 빠르게 처리할 수 있을까요?
답변1
파일 모드 옵션(-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
스크립트에 두 가지 오류가 있습니다.
$itemToFind
grep은 작은따옴표 사이에 문자열을 넣기 때문에 문자열 일치를 시도합니다'
. 대신 큰따옴표를 사용하세요.인덱스 1의 배열을 사용하고 있으며
help read
0에서 시작하도록 지시하고 있습니다.
이는 다음을 제공해야 합니다.
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}'