배열 값으로 grep하여 더 빠르게 만듭니다.

배열 값으로 grep하여 더 빠르게 만듭니다.

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

스크립트에 두 가지 오류가 있습니다.

  • $itemToFindgrep은 작은따옴표 사이에 문자열을 넣기 때문에 문자열 일치를 시도합니다 '. 대신 큰따옴표를 사용하세요.

  • 인덱스 1의 배열을 사용하고 있으며 help read0에서 시작하도록 지시하고 있습니다.

이는 다음을 제공해야 합니다.

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

관련 정보