구분된 파일을 변환하려면 쉘 명령이 필요합니다. 입력 파일은 큰 따옴표가 있는 것과 따옴표가 없는 두 가지 변형으로 수신되었으며 두 파일 모두 구분 기호로 쉼표가 있었습니다. 요구 사항은 쉼표를 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'
반복되지 않는 표현식을 그룹화하지 않으므로 스크립트보다 훨씬 빠릅니다.
sed
GNU가 있어서 작동 하는 것 같습니다 \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