【问题标题】:Removing Extra commas from Comma delimited file从逗号分隔的文件中删除多余的逗号
【发布时间】:2013-12-10 12:05:35
【问题描述】:

我有一个 12 列的逗号分隔文件。

第 5 列和第 6 列存在问题(第 5 列和第 6 列中的文本相同,但它们之间可能有多余的逗号),其中包含多余的逗号。

 2011,123456,1234567,12345678,Hey There,How are you,Hey There,How are you,882864309037,ABC   ABCD,LABACD,1.00000000,80.2500000,One Two

所以在上面的例子中,“嘿,你好吗”不应该有逗号。

我需要删除第 5 列和第 6 列中多余的逗号。

【问题讨论】:

  • 第 4 和第 7 列总是包含数字?
  • 如果可能,最好重新请求或重新生成 csv 文件,使用逗号对列进行封装。例如2011,123456,1234567,12345678,"Hey There,How are you","Hey There,How are you",882864309037,ABC ABCD,LABACD,1.00000000,80.2500000,One Two

标签: regex perl csv sed awk


【解决方案1】:

您可以尝试使用 及其Text::CSV_XS 模块:

#!/usr/bin/env perl

use warnings;
use strict;
use Text::CSV_XS;

my (@columns);

open my $fh, '<', shift or die;

my $csv = Text::CSV_XS->new or die;
while ( my $row = $csv->getline( $fh ) ) { 
    undef @columns;
    if ( @$row <= 12 ) { 
        @columns = @$row;
        next;
    }   

    my $extra_columns = ( @$row - 12 ) / 2;
    my $post_columns_index = 4 + 2 * $extra_columns * 2;
    @columns = ( 
        @$row[0..3], 
        (join( '', @$row[4..(4+$extra_columns)] )) x 2,  
        @$row[$post_columns_index..$#$row] 
    );  
}
continue {
    $csv->print( \*STDOUT, \@columns );
    printf "\n";
}

假设输入文件 (infile) 有三行,其中第一个有一个额外的逗号,第二个有两个额外的逗号,第三个是正确的:

2011,123456,1234567,12345678,Hey There,How are you,Hey There,How are you,882864309037,ABC   ABCD,LABACD,1.00000000,80.2500000,One Two
2011,123456,1234567,12345678,Hey There,How are you,now,Hey There,How are you,now,882864309037,ABC   ABCD,LABACD,1.00000000,80.2500000,One Two
2011,123456,1234567,12345678,Hey There:How are you,Hey There:How are you,882864309037,ABC   ABCD,LABACD,1.00000000,80.2500000,One Two

像这样运行脚本:

perl script.pl infile

产生:

2011,123456,1234567,12345678,"Hey ThereHow are you","Hey ThereHow are you",882864309037,"ABC   ABCD",LABACD,1.00000000,80.2500000,"One Two"
2011,123456,1234567,12345678,"Hey ThereHow are younow","Hey ThereHow are younow",LABACD,1.00000000,80.2500000,"One Two"
2011,123456,1234567,12345678,"Hey There:How are you","Hey There:How are you",882864309037,"ABC   ABCD",LABACD,1.00000000,80.2500000,"One Two"

请注意,它添加了一些引号,但它基于 csv 规范是正确的,并且更容易处理之前的状态。

【讨论】:

    【解决方案2】:

    如果您总是想删除第 5 个逗号,请尝试

    sed 's/,//5' input.txt
    

    但您是说,它可能有多余的逗号。你必须提供一个逻辑来判断是否有多余的逗号。

    如果您知道逗号的数量,可以使用。这已被证明是一个相当大的练习,我相信其他人会想出一个更优雅的解决方案,但我还是会分享我的:

    awk -f script.awk input.txt
    

    使用 script.awk:

    BEGIN{
        FS=","
    }
    NF<=12{
        print $0
    }
    NF>12{
        for (i=1; i<=4; i++) printf $i FS
        for (j=0; j<2; j++){
            for (i=0; i<=(NF-12)/2; i++){
                printf $(i+5)
                if (i<(NF-12)/2) printf "_"
                else printf FS
            }
        }
        for (i=NF-5; i<=NF; i++) printf $i FS
        printf "n"
    }
    

    首先我们将字段分隔符设置为,。如果我们计数小于或等于12 字段,一切都很好,我们只需打印整行。如果有超过 12 个字段,我们首先打印前 4 个字段(再次使用字段分隔符),然后我们打印两次字段 5(和字段 6),但不是打印 ,,而是与 @ 987654328@。最后我们打印剩余的字段。

    正如我所说,可能有一个更优雅的解决方案。我想知道其他人会怎么想。

    【讨论】:

    • 每行应该有 11 个逗号(共 12 列),第 5 和第 6 列有多余的逗号。
    【解决方案3】:

    如果所有其他字段都是数字的,您可以尝试按照该标准保存有用的逗号。

       sed -r 's/(,)[0-9]/;/g' a | sed -r 's/[0-9](,)/;/g' |  sed -r 's/,//g' |  awk -F\; '{ print $1 "," $2 "," $3 "," $4 "," substr($5, 0, length($5)/2) "," substr($5, length($5)/2 +1, length($5)/2) "," $6 "," $7}'
    2011,23456,234567,234567,Hey ThereHow are you,Hey ThereHow are you,8286430903,
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2017-09-13
      • 2018-05-12
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多