csv 파일($file) 열에 다른 배열을 쓰려고 합니다.
각 배열에는 동일한 수의 값이 있습니다. 예를 들어 arr1과 arr2에는 각각 3개의 값이 있습니다.
arr1=( 23 45 34 )
arr2=( "abc,d" ef g )
다음 코드를 시도했지만 잘못된 결과가 나왔습니다.
for i in "${!arr1[@]}"; do
echo "${arr1[i]}, ${arr2[i]}" >> $file
done
col1, col2 및 col3이 3개의 열인 다음 결과를 얻습니다.
col1 col2 col3
23 "abc d"
45 ef
34 g
하지만 원하는 결과는
col1 col2
23 "abc,d"
45 ef
34 g
"abc,d"에 포함된 혼수 상태가 문제의 원인인 것 같습니다. 이 문제에 대한 해결책을 알고 있거나 더 나은 방법을 갖고 있는 사람이 있습니까?
미리 감사드립니다!
답변1
파일을 보는 방법(아마도 스프레드시트 프로그램을 사용합니까?)이 귀하의 질문에서 명확하지 않지만 쉘은 배열 정의에서 따옴표를 제거할 수 있습니다. 포함된 쉼표를 CSV 호환 방식으로 처리하려면 다음을 추가해야 합니다. 예를 들어 리터럴 인용문으로 사용됩니다.
arr1=( 23 45 34 )
arr2=( \"abc,d\" ef g )
따라서 쉘의 내부 표현은 다음과 같습니다.
$ declare -p arr1 arr2
declare -a arr1=([0]="23" [1]="45" [2]="34")
declare -a arr2=([0]="\"abc,d\"" [1]="ef" [2]="g")
예를 들어
for i in "${!arr1[@]}"; do
printf '%s,%s\n' "${arr1[i]}" "${arr2[i]}"
done > "$file"
밝혀지다
$ cat "$file"
23,"abc,d"
45,ef
34,g
또 다른 옵션은 모든 필드를 인용하는 것입니다.
arr1=( 23 45 34 )
arr2=( "abc,d" ef g )
for i in "${!arr1[@]}"; do
printf '"%s","%s"\n' "${arr1[i]}" "${arr2[i]}"
done > "$file"
주다
$ cat "$file"
"23","abc,d"
"45","ef"
"34","g"
답변2
이 답변에서는 데이터에 텍스트 탭이 포함되어 있지 않다고 가정합니다.
먼저 각 배열에 대한 간단한 열(헤더 포함)을 만든 후 다음을 사용하여 결합합니다 paste
.
#!/bin/bash
arr1=( 23 45 34 )
arr2=( abc,d ef g )
paste <( echo col1; printf '%s\n' "${arr1[@]}" ) \
<( echo col2; printf '%s\n' "${arr2[@]}" )
출력은 다음과 같습니다
col1 col2
23 abc,d
45 ef
34 g
그런 다음 Miller를 사용하여 이를 적절하게 인용된 CSV로 변환할 수 있습니다.
#!/bin/bash
arr1=( 23 45 34 )
arr2=( abc,d ef g )
paste <( echo col1; printf '%s\n' "${arr1[@]}" ) \
<( echo col2; printf '%s\n' "${arr2[@]}" ) | mlr --t2c cat
이것은 생성됩니다
col1,col2
23,"abc,d"
45,ef
34,g
... CSV 인식 프로그램은 다음과 같이 읽습니다.
열 1 | 2열 |
---|---|
이십 삼 | ABCD |
45 | 에브 |
34 | G |
CSV를 지원하는 스프레드시트 프로그램은 TSV 데이터도 읽을 수 있으므로 Miller가 꼭 필요한 것은 아닙니다.