如何在某些列中按换行符(\ n)分割值,提取到新行并填充其他列
我的示例CSV数据(data.csv)
No,Email,IP,Service,Comment
1,test@email.com,192.168.10.109,FTP
HTTP
HTTPS,,
2,webmaster@email.com,192.168.10.111,SFTP
SNMP,,
3,admin@email.com,192.168.10.112,HTTP,,
“服务”列中有多个值,用新行分隔。
我要提取它并在其他行中填充其他值,如下所示。
1,test@email.com,192.168.10.110,FTP,,
1,test@email.com,192.168.10.110,HTTP,,
1,test@email.com,192.168.10.110,HTTPS,,
2,webmaster@email.com,192.168.10.111,SFTP,,
2,webmaster@email.com,192.168.10.111,SNMP,,
3,admin@email.com,192.168.10.112,HTTP,,
我尝试使用Text :: CSV进行解析,我只能拆分多个ip和服务,但是我不知道要像上面的示例那样填充其他值。
#!/usr/bin/perl
use Text::CSV;
my $file = "data.csv";
my @csv_value;
open my $fh, '<', $file or die "Could not open $file: $!";
my $csv = Text::CSV->new;
my $sum = 0;
open(my $data, '<:encoding(utf8)', $file) or die "Could not open '$file' $!\n";
while (my $fields = $csv->getline( $data )) {
push @csv_value, $fields;
}
close $data;
在此先感谢您提供的帮助。
答案 0 :(得分:1)
扩大我的评论
perl -ne 'if (!/^\d/){print "$line$_";} else {print $_;} /(.*,).*/; $line=$1;' file1
e = inline command
n = implicit loop, i.e. for every line in the file do the script
文件的每一行现在都在$ _默认变量中
if (!/^\d/){print "$line$_";} - if the line does not start with a digit print the $line (more later) variable, followed by default variable which is the line from the file
else {print $_;} - else just print the line
现在,在执行此操作后,如果该行与任何字符匹配,然后跟一个逗号,然后匹配任何东西,请用正则表达式括起来将其放入$ 1中。因此,对于第一行,$ 1将为“ 1,test @ email.com,192.168.10.109,”
/(.*,).*/; $line=$1;
因为我们在打印第一行之后执行此操作,所以$ line始终是前一个完整行。
答案 1 :(得分:0)
您输入的CSV损坏。我建议修复发电机。
如果使用正确格式的输入CSV,则您必须在Text::CSV中启用binary
选项,因为您的数据包含非ASCII字符。
#!/usr/bin/perl
use strict;
use warnings;
use Text::CSV;
# input has non-ASCII characters
my $csv_in = Text::CSV->new({ binary => 1 });
my $csv_out = Text::CSV->new();
$csv_out->eol("\n");
while (my $row = $csv_in->getline(\*STDIN)) {
for my $protocol (split("\n", $row->[3])) {
$row->[3] = $protocol;
$csv_out->print(\*STDOUT, $row);
}
}
exit 0;
使用固定的输入数据进行测试:
$ cat dummy.csv
No,Email,IP,Service,Comment
1,test@email.com,192.168.10.109,"FTP
HTTP
HTTPS",,
2,webmaster@email.com,192.168.10.111,"SFTP
SNMP",,
3,admin@email.com,192.168.10.112,HTTP,,
$ perl dummy.pl <dummy.csv
No,Email,IP,Service,Comment
1,test@email.com,192.168.10.109,FTP,,
1,test@email.com,192.168.10.109,HTTP,,
1,test@email.com,192.168.10.109,HTTPS,,
2,webmaster@email.com,192.168.10.111,SFTP,,
2,webmaster@email.com,192.168.10.111,SNMP,,
3,admin@email.com,192.168.10.112,HTTP,,