[unix] CSV를 TSV로 변환

대용량 CSV 파일이 많이 있으며 TSV (탭으로 구분 된 형식) 형식으로 원합니다. 합병증은 CSV 파일의 필드에 쉼표가 있다는 것입니다. 예를 들면 다음과 같습니다.

 A,,C,"D,E,F","G",I,"K,L,M",Z

예상 출력 :

 A      C   D,E,F   G   I   K,L,M   Z

(사이의 공백은 ‘하드’탭입니다)

이 서버에 Perl, Python 및 coreutils가 설치되어 있습니다.



답변

파이썬

라는 파일에 추가 csv2tab.sh하고 실행 가능하게 만드십시오.

#!/usr/bin/env python
import csv, sys
csv.writer(sys.stdout, dialect='excel-tab').writerows(csv.reader(sys.stdin))

시운전

$ echo 'A,,C,"D,E,F","G",I,"K,L,M",Z' | ./csv2tab.sh
A       C   D,E,F   G   I   K,L,M   Z

$ ./csv2tab.sh < data.csv > data.tsv && head data.tsv
1A      C   D,E,F   G   I   K,L,M   Z
2A      C   D,E,F   G   I   K,L,M   Z
3A      C   D,E,F   G   I   K,L,M   Z


답변

재미를 위해 sed.

sed -E 's/("([^"]*)")?,/\2\t/g' file

sed지원하지 않는 경우로 -E시도하십시오 -r. 리터럴 탭을 sed지원하지 않는 경우 \t리터럴 탭 (많은 쉘, ctrlv tab) 또는 Bash에 $'...'C 스타일 문자열을 사용하십시오 (이 경우 백 슬래시를 \2두 배로 늘려야 함). 따옴표를 유지하려면 \1대신 사용하십시오 \2(이 경우 괄호의 내부 쌍은 쓸모 없으며 제거 할 수 있음).

이것은 큰 따옴표 안의 이스케이프 된 큰 따옴표를 처리하려고 시도하지 않습니다. 일부 CSV 방언은 인용 된 큰 따옴표 (sic)를 두 배로하여이를 지원합니다.


답변

csvkit유틸리티 (Python) 사용 예 :

$ csvformat -T in.csv > out.txt

올바른 CSV 및 TSV 인용 및 이스케이프를 사용하여 스트리밍

apt 및 기타 패키지 관리자에 있습니다.


답변

하나의 옵션은 펄의 Text :: CSV 모듈입니다.

perl -MText::CSV -lne 'BEGIN { $csv = Text::CSV->new() }
  print join "\t", $csv->fields() if $csv->parse($_)
' somefile

설명하기 위해

echo 'A,,C,"D,E,F","G",I,"K,L,M",Z' |
  perl -MText::CSV -lne 'BEGIN { $csv = Text::CSV->new() }
  print join "\t", $csv->fields() if $csv->parse($_)
'
A       C   D,E,F   G   I   K,L,M   Z


답변

perl -lne '
   my $re = qr/,(?=(?:[^"]*"[^"]*")*(?![^"]*"))/;
   print join "\t", map { s/(?<!\\)"//gr =~ s/\\"/"/gr } split $re;
'

어 wk

awk -v Q=\" -v FPAT="([^,]*)|(\"[^\"]+\")" -v OFS="\t" '{
   for (i=1; i<=NF; ++i)
      if ( substr($i, 1, 1) == Q )
         $i = substr($i, 2, length($i) - 2)
   print $1, $2, $3, $4, $5, $6, $7, $8
}'

결과:

A               C       D,E,F   G       I       K,L,M   Z


답변

열핵 플라이스와 터 솔루션은 libreoffice를 사용해야합니다. https://ask.libreoffice.org/en/question/19042/is-is-possible-to-convert-comma-separated-value-csv-to-tab-separated-value-tsv-via-headless-mode 동안 / 이것이 가능하지는 않지만 잘못되었거나 오래 되었습니까? 다음 명령은 5.3에서 작동합니다.

loffice "-env:UserInstallation=file:///tmp/LibO_Conversion" --convert-to csv:"Text - txt - csv (StarCalc)":9,34,UTF8 --headless --outdir some/path --infilter='csv:44,34,UTF8' *.csv

env인수는 생략 될 수 있지만,이 방법은 문서를 최근 문서에 표시되지 않습니다.


답변

csvtool유틸리티가 있거나 설치할 수있는 경우 :

csvtool -t COMMA -u TAB cat in.csv > out.ctv

어떤 이유로 csvtool매뉴얼 페이지가 없지만 csvtool --help수백 줄의 문서를 인쇄합니다.