使用sed填充空的CSV字段?

时间:2013-03-06 09:10:31

标签: perl csv sed

我需要在文件中的所有空单元格(没有任何值)中输入一些值(例如 1)。如何使用完成?

如果使用无法实现这一目标,那么可以做到这一点吗?

3 个答案:

答案 0 :(得分:6)

我认为使用或Perl one liners操纵CSV文件至少可以说是乐观的。如果格式改变了,如果一个字段包含分隔符怎么办?我建议使用Text::CSV_XS,这非常简单有效。通常,简单的任务,例如您要求的只需要几行。如果配置正确Text::CSV_XS实例($csv),则只能是:

while ( my $row = $csv->getline( $in ) ) {
  my @new_row = map { defined $_ ? $_ : 1 } @$row;
  $csv->print( \*STDOUT, \@new_row );
}

如果你仍然想直接使用命令行,你可以检查csv (App::CSV),哪个IMO比上面提到的替代方法有更好的方法。

答案 1 :(得分:3)

可以使用awk完成。你可以尝试:

awk '{for(i=1; i<=NF; i++) if($i=="") $i=1}1' FS=, OFS=, file

-----

阅读Larsen的评论我意识到他是正确的,因为OP没有真正发布一个样本,可以显示是否会出现引用字段。我试图找到一个简单的更通用的方法,试图采取这个考虑到..

awk '
  {
    for(i=1; i<=NF; i++) {                              # For every field
      if($i=="")                                        # it is empty 
        $i=1                                            # then make it 1 requirement OP
      else {
        f=$i                                            # set `f` to the current field
        while( gsub(/"/,"&",f )%2 && i<NF ) f=f $(++i)  # while the total number of double quotes is odd, keep adding the next field to the current field and ignore it..
      }
    }
  }
  1                                                     # print the record
' FS=, OFS=, file                                       # set the I/O field separators to `,`

或者在一行中:

awk '{for(i=1; i<=NF; i++) if($i=="") $i=1; else { f=$i; while( gsub(/"/,"&",f)%2 && i<NF) f=f $(++i)}}1' FS=, OFS=, file

使用此输入进行测试:

,1997,Ford,,"Super, ""luxurious"" ,,,truck",,
0,1997,Ford,,"Super, ""luxurious"" ,,,truck",,,,

制作人:

1,1997,Ford,1,"Super, ""luxurious"" ,,,truck",1,1
0,1997,Ford,1,"Super, ""luxurious"" ,,,truck",1,1,1,1

答案 2 :(得分:2)

怎么样:

$ cat file
v,,v,,,v,v,,,,
,,v,,v,v,,,v,,,v
,,,,,,,,,,,,,,

$ sed -e 's/^,/v,/' -e':a;s/,,/,v,/;ta' -e 's/,$/,v/' file
v,v,v,v,v,v,v,v,v,v,v
v,v,v,v,v,v,v,v,v,v,v,v
v,v,v,v,v,v,v,v,v,v,v,v,v,v,v

如果您对这些更改感到满意,请使用-i选项将更改存储回文件。

$ sed -i -e 's/^,/v,/' -e':a;s/,,/,v,/;ta' -e 's/,$/,v/' file