쉼표로 구분된 문자열만 따옴표로 묶습니다.

쉼표로 구분된 문자열만 따옴표로 묶습니다.

현재 TSV 형식이지만 CSV 형식으로 변환해야 하는 일부 데이터가 있습니다. 유일한 문제는 때때로 TSV에서 쉼표가 포함된 일부 값이 항상 동일한 열에 있지 않다는 것입니다(쉼표의 개수도 각 인스턴스마다 다를 수 있음). CSV를 올바르게 구문 분석할 수 있도록 쉼표로 구분된 문자열을 따옴표로 묶고 싶습니다.

내가 가진 것(TSV):

Freddy, Jasmine, and Lucy     412      Penguin
Maggie    5,432    salad
Joe       4        John Smith, PhD  

내가 원하는 것(CSV):

"Freddy, Jasmine, Lucy",412,Penguin
this,"5,432",salad
Joe,4,"John Smith, PhD"

Bash에서 이 작업을 수행할 수 있는 방법이 있나요?

답변1

이것csvformat도구:CSV 키트당신이 원하는 것을 정확하게 할 것입니다:

csvformat --tabs inputFile.dat

printf "%s\n" \
    $'Freddy, Jasmine, and Lucy\t412\tPenguin' \
    $'Maggie\t5,432\tsalad' \
    $'Joe\t4\tJohn Smith, PhD' >inputFile.dat

csvformat --tabs inputFile.dat

산출

"Freddy, Jasmine, and Lucy",412,Penguin
Maggie,"5,432",salad
Joe,4,"John Smith, PhD"

답변2

이런 종류의 일을 위한 또 다른 유용한 도구는밀러- 빌리다@roaima에 대한 입력 파일

$ mlr --itsv --ocsv cat inputFile.dat
"Freddy, Jasmine, and Lucy",412,Penguin
Maggie,"5,432",salad
Joe,4,"John Smith, PhD"

답변3

CSV 모듈과 함께 번들로 제공되는 프로그래밍 언어를 사용하여 이 작업을 수행하는 것은 csvkit 또는 miller보다 더 장황합니다.

ruby -rcsv -e '
    csvin = CSV.new(File.new(ARGV.shift), col_sep: "\t")
    csvout = CSV.new($stdout)
    csvin.each {|row| csvout.puts(row)}
' file.tsv

또는

ruby -rcsv -e 'CSV.foreach(ARGV.shift, col_sep: "\t") {|row| puts CSV.generate_line(row)}' file.tsv

산출

"Freddy, Jasmine, and Lucy",412,Penguin
Maggie,"5,432",salad
Joe,4,"John Smith, PhD  "

샘플 데이터의 마지막 행에는 후행 공백이 있습니다.

관련 정보