[linux] Bash에서 CSV 파일을 구문 분석하는 방법은 무엇입니까?

긴 Bash 스크립트를 작성 중입니다. CSV 파일의 셀을 Bash 변수로 읽고 싶습니다. 줄과 첫 번째 열을 구문 분석 할 수 있지만 다른 열은 구문 분석 할 수 없습니다. 지금까지 내 코드는 다음과 같습니다.


  cat myfile.csv|while read line
  do
    read -d, col1 col2 < <(echo $line)
    echo "I got:$col1|$col2"
  done

첫 번째 열만 인쇄합니다. 추가 테스트로 다음을 시도했습니다.

read -d, x y < <(echo a,b,)

그리고 $ y는 비어 있습니다. 그래서 나는 시도했다.

read x y < <(echo a b)

그리고 $ y는 b입니다. 왜?



답변

IFS대신 -d다음 을 사용해야 합니다 .

while IFS=, read -r col1 col2
do
    echo "I got:$col1|$col2"
done < myfile.csv

범용 CSV 구문 분석의 경우 Bash가 자체적으로 처리 할 수없는 다른 문제 중에서도 내부 쉼표로 인용 된 필드를 처리 할 수있는 특수 도구를 사용해야합니다. 이러한 도구의 예는 cvstoolcsvkit입니다.


답변

로부터 man페이지 :

-d delim delim의 첫 번째 문자는 줄 바꿈이 아닌 입력 줄을 종료하는 데 사용됩니다.

-d,쉼표에서 입력 줄을 종료하는 사용 중입니다. 나머지 줄은 읽지 않습니다. 이것이 $ y가 비어있는 이유입니다.


답변

인용 문자열로 csv 파일을 구문 분석하고 say | 다음 코드로

while read -r line
do
    field1=$(echo $line | awk -F'|' '{printf "%s", $1}' | tr -d '"')
    field2=$(echo $line | awk -F'|' '{printf "%s", $2}' | tr -d '"')

    echo $field1 $field2
done < $csvFile

awk는 문자열 필드를 변수로 구문 분석하고 tr은 따옴표를 제거합니다.

awk가 각 필드에 대해 실행되므로 약간 느립니다.


답변

일부 줄이있는 CSV 파일을 읽으려면 이것이 해결책입니다.

while IFS=, read -ra line
do 
    test $i -eq 1 && ((i=i+1)) && continue
    for col_val in ${line[@]}
    do
        echo -n "$col_val|"                 
    done
    echo        
done < "$csvFile"


답변