CSV 파일 처리 - 따옴표를 제거하고 쉼표 구분 기호를 탭으로 바꿉니다.

CSV 파일 처리 - 따옴표를 제거하고 쉼표 구분 기호를 탭으로 바꿉니다.

구분된 파일을 변환하려면 쉘 명령이 필요합니다. 입력 파일은 큰 따옴표가 있는 것과 따옴표가 없는 두 가지 변형으로 수신되었으며 두 파일 모두 구분 기호로 쉼표가 있었습니다. 요구 사항은 쉼표를 TAB으로 바꾸고 따옴표를 제거하는 것입니다(파일에 큰따옴표가 있는 경우). 그렇지 않으면 쉼표만 바꾸면 됩니다. 파일 필드에 변환 중에 무시해야 하는 쉼표도 포함되어 있는 경우 파일은 따옴표와 함께 전송됩니다. 단일 명령은 RHEL 6.x 환경의 Awk 3.x에서 작동해야 합니다.

예를 들어. 큰따옴표가 있는 파일 1:

"Jhon","Carpenter","CA,TX,NJ"
"Mike","Painter","WA,GA,MI"

변환 후에는 탭으로 구분되어야 합니다.

Jhon   Carpenter   CA,TX,NJ 
Mike   Painter     WA,GA,MI 

예를 들어. 큰따옴표가 없는 파일 2:

EMP1,123456,CA 
EMP2,456789,TX 

변환 후에는 탭으로 구분되어야 합니다.

EMP1 123456   CA 
EMP2   456789   TX

답변1

사용csvkit:

$ csvformat -T file1.csv
Jhon    Carpenter       CA,TX,NJ
Mike    Painter WA,GA,MI

$ csvformat -T file2.csv
EMP1    123456  CA
EMP2    456789  TX

출력이 file1.csv약간 잘못된 것처럼 보이지만 이는 탭이 올바르게 정렬되지 않았기 때문일 뿐입니다. 모든 열 사이에는 탭이 있습니다.

CSVKit은 다양한 CSV 관련 셸 유틸리티가 포함된 Python 기반 툴킷입니다. 올바른 CSV 구문 분석을 수행하고 CSV 파일을 쿼리, 형식 지정 및 변환하는 데 사용할 수 있습니다.

예를 들어 첫 번째 파일에 올바른 헤더가 있는 경우 이를 JSON으로 변환하는 것은 간단합니다.

$ csvjson file1.csv
[{"First": "Jhon", "Last": "Carpenter", "Stuff": "CA,TX,NJ"}, {"First": "Mike", "Last": "Painter", "Stuff": "WA,GA,MI"}]

답변2

이 짧은 sed스크립트는 두 가지 유형의 파일을 모두 처리할 수 있습니다(첫 번째 유형과 두 번째 유형이 포함된 혼합 파일도 포함).

sed '/"/!s/,/\t/g;s/","/\t/g; s/"//g'

반복되지 않는 표현식을 그룹화하지 않으므로 스크립트보다 훨씬 빠릅니다.

sedGNU가 있어서 작동 하는 것 같습니다 \t. 그렇지 않으면 대신 리터럴 TAB을 사용하십시오.

답변3

몇 가지 방법들:

(큰따옴표 사용 file1):

--방법:

awk -F'"' '{ r=""; for(i=1;i<NF;i++) 
     if ($i~/^[[:alnum:]]/) r=(r!="")? r OFS $i : $i; print r }' OFS='\t' file1

--sed방법:

sed 's/","/\t/g; s/"//g;' file1

출력(두 방법 모두):

Jhon    Carpenter   CA,TX,NJ
Mike    Painter WA,GA,MI

----------

( file2큰따옴표 제외) - tr다음 명령을 적용하면 충분합니다.

tr ',' '\t' <file2

산출:

EMP1    123456  CA
EMP2    456789  TX

----------

조건에 대한 통일된 접근 방식"두 파일 형식 모두에 대해 동일한 명령으로 충분해야 합니다.":

awk -v quoted=$(grep -cm1 '"' file1) 'BEGIN{ FS=(quoted)? "\"" : ","; }
     { r=""; for(i=1;i<=NF;i++) if(!quoted || $i~/^[[:alnum:]]/) r=(r!="")? r OFS $i : $i; 
             print r }' OFS='\t' file1

답변4

CSV 데이터에는 적절한 CSV 파서가 필요합니다. 나는 Kusarananda의 답변을 좋아합니다. csv 모듈과 함께 Ruby와 같은 언어를 사용할 수도 있습니다.

ruby -rcsv -e '
  out = CSV.new($stdout, {:col_sep => "\t"})
  CSV.foreach(ARGV.shift) {|row| out << row} 
' file1.csv

관련 정보