【问题标题】:How do I format a Date field of a .CSV file with multiple commas in a string field如何在字符串字段中使用多个逗号格式化 .CSV 文件的日期字段
【发布时间】:2013-10-24 01:33:23
【问题描述】:

我有一个 .CSV 文件 (file.csv),其数据全部用双引号括起来。文件示例格式如下:

column1,column2,column3,column4,column5,column6, column7, Column8, Column9, Column10
"12","B000QRIGJ4","4432","string with quotes, and with a comma, and colon: in between","4432","author1, name","890","88","11-OCT-11","12"
"4432","B000QRIGJ4","890","another, string with quotes, and with more than, two commas: in between","455","author2, name","12","455","12-OCT-11","55"
"11","B000QRIGJ4","77","string with, commas and (paranthesis) and : colans, in between","12","author3, name","333","22","13-OCT-11","232"

第 9 个字段是格式为 “DD-MMM-YY” 的日期字段。我必须将其转换为 YYYY/MM/DD 格式。我正在尝试使用下面的代码,但没有用。

awk -F, '
 BEGIN {
 split("JAN FEB MAR APR MAY JUN JUL AUG SEP OCT NOV DEC", month, " ")
 for (i=1; i<=12; i++) mdigit[month[i]]=i
 }
 { m=substr($9,4,3)
 $9 = sprintf("%02d/%02d/"20"%02d",mdigit[m],substr($9,1,2),substr($9,8,20))
 print
 }' OFS="," file.csv > temp_file.csv

执行上述代码后文件temp_file.csv的输出如下所示。

column1,column2,column3,column4,column5,column6,column7,Column8,00/00/2000,Column10
"12","B000QRIGJ4","4432","string with quotes, and with a comma, and colon: in between","4432","author1,00/00/2000,"890","88","11-OCT-11","12"
"4432","B000QRIGJ4","890","another, string with quotes, and with more than, two commas: in between","455",00/00/2002, name","12","455","12-OCT-11","55"
"11","B000QRIGJ4","77","string with, commas and (paranthesis) and : colans, in between","12","author3,00/00/2000,"333","22","13-OCT-11","232"

据我了解,问题在于双引号中的逗号,因为我的代码也将它们考虑在内...请就以下问题提出建议:

1) 对所有字段中的所有值进行双引号是否有任何区别?如果它们有任何区别,我如何从除带有逗号的字符串之外的所有值中删除它们? 2) 对我的代码进行任何修改,以便我可以将格式为 "DD-MMM-YYYY" 的第 9 个字段格式化为 YYYY/MM/DD

【问题讨论】:

  • 你可以从头数数:NF-1
  • 我会考虑使用一个旨在处理 CSV 文件的程序——可能是csvfix。它具有内置的日期操作功能。
  • @kev 如何在上面给出的代码中使用 NF-1?我是 linuxawk 的新手。 @JonathanLeffler 我试着做man csvfix,但它没有给我任何手册页......请详细说明我怎样才能让它工作......

标签: linux csv sed awk cut


【解决方案1】:

我强烈建议您使用正确的 CSV 解析器。例如,在 Perl 中使用 Text::CSV_XS 会以正确且理智的方式完成工作。例如这个单行:

perl -MText::CSV_XS -E'$csv=Text::CSV_XS->new({eol=>"\n", allow_whitespace=>1});@m=qw(JAN FEB MAR APR MAY JUN JUL AUG SEP OCT NOV DEC);@m{@m}=(1 .. @m);while(my $row=$csv->getline(ARGV)){($d,$m,$y)=split("-",$row->[8]);$row->[8]=sprintf"%02d/%02d/%04d",$d,$m{$m},$y if $m{$m};$csv->print(STDOUT, $row)}' file.csv > temp_file.csv

【讨论】:

    【解决方案2】:

    您可以尝试以下单行:

    awk '
    BEGIN {
        FS = OFS = ","
        split("JAN FEB MAR APR MAY JUN JUL AUG SEP OCT NOV DEC", month, / /)
        for (i=1; i<=12; i++) {
            mm[month[i]]=i
        }
    }
    NR>1 { 
        gsub(/\"/, "", $(NF-1))
        split($(NF-1), d, /-/)
        $(NF-1)=q "20" d[3] "/" mm[d[2]] "/" d[1] q}1' q='"' file
    

    输出:

    column1,column2,column3,column4,column5,column6, column7, Column8, Column9, Column10
    "12","B000QRIGJ4","4432","string with quotes, and with a comma, and colon: in between","4432","author1, name","890","88","2011/10/11","12"
    "4432","B000QRIGJ4","890","another, string with quotes, and with more than, two commas: in between","455","author2, name","12","455","2011/10/12","55"
    "11","B000QRIGJ4","77","string with, commas and (paranthesis) and : colans, in between","12","author3, name","333","22","2011/10/13","232"
    

    【讨论】:

      【解决方案3】:

      你可以试试这个awk

      awk -F"\"" 'BEGIN { OFS="\"" }{ "date -d "$18" +%Y/%m/%d" | getline $18; print $0; }' yourfile.txt
      

      输出:

      "12","B000QRIGJ4","4432","string with quotes, and with a comma, and colon: in between","4432","author1,name","890","88","2011/10/11","12"
      "4432","B000QRIGJ4","890","another, string with quotes, and with more than, two commas: in between","455","author2,name","12","455","2011/10/12","55"
      "11","B000QRIGJ4","77","string with, commas and (paranthesis) and : colans, in between","12","author3,name","333","22","2011/10/13","232"
      

      【讨论】:

      • 你能解释一下代码吗?这里的“$18”代表什么?因为,当我使用您的代码时,我收到一个错误 sh: +%Y/%m/%d: No such file or directory 并打印我在我的问题
      猜你喜欢
      • 2013-11-16
      • 2012-03-04
      • 2017-09-05
      • 2018-01-01
      • 1970-01-01
      • 2015-03-11
      • 1970-01-01
      • 2020-06-23
      • 1970-01-01
      相关资源
      最近更新 更多