CSV 파일을 읽는 중 최종 값의 뒤따르는 큰따옴표를 인쇄할 수 없습니다.

CSV 파일을 읽는 중 최종 값의 뒤따르는 큰따옴표를 인쇄할 수 없습니다.

.csv 파일(Google 시트에서 생성되어 로컬 컴퓨터에 다운로드됨) 행을 자바스크립트 개체로 변환하려고 합니다. 최종 큰따옴표 인쇄를 거부하는 마지막 필드를 제외하고 모든 필드를 올바르게 출력할 수 있습니다. 또한 터미널의 출력에서 ​​후행 "]"가 잘못 배치되어 "comps" 줄의 시작 부분(끝 대신)에 배치되었습니다. 끝에 큰따옴표가 올바르게 인쇄되지 않는 이유는 무엇입니까?

#! /usr/bin/env bash

list_file="input.csv"
destination_file="output.js"

IFS=","

while read field1 field2 field3 field4 field5 field6 field7 field8 field9 field10 field11 field12 field13 field14
do
    echo '"'${field8}'": { r: "'${field2}'", g: "'${field3}'", b: "'${field4}'", hex: "'${field5}'", code: "'${field1}'", 
    desc: "'${field9}'",
    comps: ["'${field10}'", "'${field11}'", "'${field12}'", "'${field13}'", "'${field14}'"]
    },' >> $destination_file
done < $list_file

echo "};" >> $destination_file

출력의 한 줄은 다음과 같습니다.

"#288": { r: "x", g: "x", b: "x", hex: "x", code: "XXXX", 
    desc: "description here",
"], comps: ["#1", "#2", "#3", "#4", "#5
    },

세 번째 줄에는 마지막 큰따옴표와 닫는 괄호가 먼저 인쇄됩니다.

또한 각 개별 필드를 테스트할 때 다음을 사용하세요.

echo '"' $field14 '"'

마지막 필드에 대해서만 동일한 출력을 얻습니다(닫는 큰따옴표 없이). 그러나 다른 모든 필드는 예상대로 인쇄됩니다.

답변1

Shell은 텍스트 및 데이터 처리에 있어 끔찍한 언어입니다. 셸의 임무는 작업 자체를 수행하는 것이 아니라 작업을 완료하기 위해(그리고 꽤 능숙하게) 다른 프로그램의 실행을 조정하는 것입니다. 텍스트(및 CSV) 처리에 더 적합한 언어를 사용하십시오. 예를 들어, 펄은 다음과 같습니다.

$ cat csv-to-js.pl 
#!/usr/bin/perl

use strict;
use Text::CSV qw(csv);

my $fmt = <<__EOF__;
"%s": { r: "%s", g: "%s", b: "%s", hex: "%s", code: "%s",
    desc: "%s",
    comps: ["%s", "%s", "%s", "%s", "%s"],
    },
__EOF__

# default to reading stdin if no args are supplied
push @ARGV, '/dev/stdin' unless (@ARGV);

my $csv = Text::CSV->new();

foreach my $f (@ARGV) {
  open my $fh, "<", $f or die "$f: $!";
  while (my $row = $csv->getline($fh)) {
    printf $fmt, @$row[7,1..4,0,8,9..13]; # perl arrays start from 0, not 1
  };
  close $fh;
}

이는 다음을 사용합니다.텍스트::CSVCore Perl에 포함되지 않은 모듈은 별도로 설치해야 합니다. Debian 및 Ubuntu 및 Mint와 같은 파생 제품에서는 sudo apt-get install libtext-csv-perl.cpan

스크립트는 printf에 대한 형식 문자열을 만들고 명령줄에 나열된 CSV 파일을 열고 각 줄을 읽고 구문 분석한 다음 printf를 사용하여 인쇄합니다.

그런데 이 스크립트는 줄이 LF(유닉스 텍스트 파일)로 끝나는지 CR/LF(dos/windows 텍스트 파일)로 끝나는지 관계없이 작동합니다.

입력 예:

$ cat input.csv 
XXXX,x,x,x,x,6,7,"#288","description here","#1","#2","#3","#4","#5"
YYYY,x,x,x,x,6,7,"#289","another description here","#1","#2","#3","#4","#5"
ZZZZ,x,x,x,x,6,7,"#290","and another description here","#1","#2","#3","#4","#5"

샘플 실행:

$ ./csv-to-js.pl input.csv 
"#288": { r: "x", g: "x", b: "x", hex: "x", code: "XXXX",
    desc: "description here",
    comps: ["#1", "#2", "#3", "#4", "#5"],
    },
"#289": { r: "x", g: "x", b: "x", hex: "x", code: "YYYY",
    desc: "another description here",
    comps: ["#1", "#2", "#3", "#4", "#5"],
    },
"#290": { r: "x", g: "x", b: "x", hex: "x", code: "ZZZZ",
    desc: "and another description here",
    comps: ["#1", "#2", "#3", "#4", "#5"],
    },

답변2

의견을 보내주셔서 감사합니다. 마지막 필드로 끝나는 CRLF 줄을 제거하기 위해 이 줄을 추가했고 코드는 예상대로 인쇄되었습니다.

field14=$(echo $field14 | sed 's/\r//g')

관련 정보