CSV 파일에서 수집된 일부 데이터를 처리하는 스크립트를 작성 중입니다. 데이터를 여러 배열(파일의 각 열에 대해 하나의 배열)로 읽었습니다. 이제 실제로 모든 데이터를 순차적으로 처리해야 합니다.
현재 나는 이것을하고 있습니다 :
# Read in the data:
declare -a DATACOL1 DATACOL2 RAWDATA
RAWDATA=($( sed '1d' /path/to/data.csv )) # Remove the header line
for line in ${RAWDATA[@]}; do
declare -a LINEDATA LINE
LINE=$( echo "$line" | sed 's/,/ /g' )
for field in LINE; do
LINEDATA+=("${field}")
done
DATACOL1+=(${LINEDATA[0]})
DATACOL2+=(${LINEDATA[1]})
done
# Work on the data:
for i in $( seq 0 $[${#DATACOL1[@]}-1}; do
stuff and things with ${DATACOL1[i]} and ${DATACOL2[i]}
done
내 (가장 상호 연관되어 있는) 질문은 두 가지입니다.
데이터를 반복하는 것보다 데이터를 처리하는 더 우아한 방법이 있습니까
for i in $( seq 0 $[${#DATACOL1[@]}-1}
? 작동하지만 추악합니다.CSV 데이터를 얻는 더 우아한 방법이 있습니까?
이것은 bash 3에 있으므로 연관 배열이 없습니다.
답변1
나는 다음과 같이 쓸 것이다:
mapfile -t rawdata < <(sed 1d /path/to/data.csv)
datacol1=()
datacol2=()
for line in "${rawdata[@]}"; do
IFS=, read -ra fields <<< "$line"
datacol1+=( "${fields[0]}" )
datacol2+=( "${fields[1]}" )
done
for ((i=0; i < "${#datacol1[@]}"; i++)); do
stuff with "${datacol1[i]}" and "${datacol2[i]}"
done
mapfile
파일의 행을 배열로 읽는 데 사용됩니다 .- 및를 사용하여 줄에서 쉼표로 구분된 필드를 읽습니다
IFS
.read
- 인용된 문자열에서 쉼표로 구분됩니다.실제 CSV 파서를 사용하세요.
for
seq 호출을 피하기 위해 C와 유사한 형식을 사용하십시오.
물론 두 번째 루프나 datacol* 변수는 필요하지 않습니다.
for line in "${rawdata[@]}"; do
IFS=, read -a fields <<< "$line"
stuff with "${fields[0]}" and "${fields[1]}"
done
Bash 3에서는 그런 기능이 없으므로 mapfile
while 루프를 사용하십시오.
datacol1=()
datacol2=()
while IFS=, read -ra fields; do
datacol1+=("${fields[0]}")
datacol2+=("${fields[1]}")
done < <(sed 1d /path/to/data.csv)