csv 파일의 단일 행(인덱싱된)을 zsh 배열로 가져올 수 있나요?

csv 파일의 단일 행(인덱싱된)을 zsh 배열로 가져올 수 있나요?

zsh에서 csv 파일을 한 줄씩 구문 분석하고 쉼표 없이 배열에 저장하고 싶습니다. zsh에서 행을 배열로 가져온 후 다음 행을 가져올 수 있습니까?

문제는 대용량 csv 파일을 사용하고 있는데 모든 파일을 빠르게 가져올 수 없다는 것입니다. 다음 코드를 사용해 보았습니다.

arr_csv=() 
while IFS= read -r line 
do
    arr_csv+=("$line")
done < import.csv

그런데 파일이 크기 때문에 한 행을 읽고 저장(또는 한 행에 액세스)하고 싶습니다.

다음과 같이 코드를 수정할 수 있다는 것을 알고 있습니다.

arr_csv=() 
while IFS= read -r line 
do
    arr_csv=("$line")
    # some modifications
done < import.csv

하지만 파일을 반복하고 싶다면 csv 파일의 행에 해당하는 인덱스를 사용할 수 있으면 더 쉬울 것입니다. 또한 이 방법은 줄을 구분하는 쉼표를 제거하지 않습니다.

답변1

제가 말하려는 것은 셸이 아닌 perl/...here 와 같은 CSV 지원이 포함된 올바른 프로그래밍 언어를 사용해야 한다는 것입니다.python

그러나 zsh개별 셀에서 줄 바꿈과 캐리지 리턴을 사용해야 하고 제거하는 데 신경 쓰지 않는다면 csvkit을 사용하여 csv를 더 쉽게 처리 할 수 csvformat있는 형식으로 다시 포맷 할 수 있습니다.zshread

< file.csv csvformat -SU3 -P'\' |
  while IFS=, read -A array; do
    typeset array # or anything with $array
  done

예를 들어 다음과 같은 입력의 경우:

"foo bar ", "x,y", "blah""blah","new
line"
1,,2,"\\"

csv와 관련된 일반적인 잠재적 함정의 예는 다음과 같습니다.

array=( 'foo bar ' x,y 'blah"blah' newline )
array=( 1 '' 2 '\\' )

누락된 경우 -r이스케이프 문자로 read인식됩니다 . \불행하게도 로 이스케이프되었지만 csvformat개행 문자를 이스케이프하는 것이 아니라 줄 연속으로 해석됩니다.<newline>\<newline>read

입력에 전혀 나타나지 않는 두 문자를 알고 있는 경우 이를 각각 필드 구분 기호와 레코드 구분 기호로 사용할 수 있습니다. 예를 들어 ASCII일 수 있습니다.기록 구분 기호그리고단위 구분 기호여기에는 제어 문자가 적절한 것 같습니다.

us=$'\x1f' rs=$'\x1e'
< file.csv csvformat -SU3 -D$us -M$rs -Q$rs |
  while IFS=$us read -rd$rs -A array; do
    something with $array
  done

이번에는 동일한 입력이 주어지면 다음과 같습니다.

array=( 'foo bar ' x,y 'blah"blah' $'new\nline' )
array=( 1 '' 2 '\\' )

관련 정보