如何根据第一列修改CSV文件的第二列?

时间:2011-03-06 16:03:19

标签: perl email csv

我是Perl的新手,我有一个包含电子邮件和名称的CSV文件,如下所示:

john@domain1.com;John
Paul@domain2.com;
Richard@domain3.com;Richard
Rob@domain4.com;
Andrew@domain5.com;Andrew

但是,正如您可以看到一些条目/行具有电子邮件地址和;字段分隔符,但缺少名称。我需要逐行阅读,如果缺少名称字段,我想在这个地方打印电子邮件的开头,直到@ domainX.com。输出示例:

john@domain1.com;John
Paul@domain2.com;Paul
Richard@domain3.com;Richard
Rob@domain4.com;Rob
Andrew@domain5.com;Andrew

我是Perl的新手,我逐行进行了读取迭代,例如:

#!/usr/bin/perl
use warnings;
use strict;

open (MYFILE, 'test.txt');
while (<MYFILE>) {
    chomp;
}

但是我没有解析条目以使用;作为分隔符,并检查名称字段是否缺失,从而打印没有域的电子邮件的开头。

有人可以根据我的代码给我一个例子吗?

3 个答案:

答案 0 :(得分:3)

首先,如果文件可能包含真实的 CSV(或你的情况下的空间SV)数据(例如引用的字段),我强烈建议使用标准的Perl模块来解析它。

否则,一个快速而肮脏的例子可以是:

#!/usr/bin/perl

use warnings;
use strict;

# In modern Perl, please always use 3-aqr form of open and lexical filehandles.
# More robust
open $fh, "<", 'test.txt' || die "Can not open: $!\n";

while (<$fh>) {
    chomp;
    my ($email, name) = split(/;/, $_);
    if (!$name) {
        my ($userid, $domain) = split(/\@/, $email);
        $name = $userid;
    }
    print "$space_prefix$email;$name\n"; # Print to STDOUT for simplicity of example
}
close($fh);

答案 1 :(得分:0)

尝试:

#!/usr/bin/env perl

use strict;
use warnings;

for my $file ( @ARGV ){

  open my$in_fh, '<', $file or die "could not open $file: $!\n";

  while( my $line = <$in_fh> ){
    chomp( $line );

    my ( $email, $name ) = split m{ \; }msx, $line;
    if( ! ( defined $name && length( $name ) > 0 ) ){
      ( $name ) = split m{ \@ }msx, $email;
      $name = ucfirst( lc( $name ));
    }

    print "$email;$name\n";
  }
}

答案 2 :(得分:-1)

我不是一个珍珠程序员,但我会首先拆分空间角色,然后你可以迭代结果并用分号分开。然后,您可以检查分号分割数组的第二个成员,如果它是空的,则将其替换为分号分割数组的第一个成员的开头。然后,只需反转过程,首先用分号连接,然后用空格连接。