我正在处理一些CSV文件。最后一个字段有时会丢失数据,如下所示:
first,last
John,Smith
Francis,
这在尝试加载到数据库中时导致提取错误。我想在crlf
之前的最后一个逗号之后添加一个空格或其他“填充符”,但是我很难用搜索/替换填充它。我已经尝试了以下示例:
$data =~ s/,\x0d\x0a/,\x20\x0d\0xa/gi
,但在crlf
之前没有添加空格。
当然,我需要保留行尾,以便正确标记行。
我尝试使用Path :: Tiny和通用open
进行阅读,但到目前为止没有成功。
答案 0 :(得分:1)
首先:使用一个模块来处理csv文件,其中一个不错的方法是Text::CSV
现在,对于这样的工作,这一次,只需一个简单的过滤器就可以了:
my $line = q(first,last John,Smith Francis,);
$line =~ s/.*,\K$/filled_last_field/;
贪婪的.*
最多匹配以下模式(在此处为逗号)的 last 实例。
\K
form中的positive lookbehind
放弃所有先前的比赛,以免被消耗;因此它只会替换其后的模式(在这种情况下,根据需要添加短语)。
如果您想先替换文件,则逐行阅读并将更改后的行写入新文件,然后将其移到旧文件上。
open my $fh, '<', $file or die "Can't open $file: $!";
open my $fh_out, '>', $new_file or die "Can't open $new_file: $!";
while (<$fh>) {
print $fh_out s/.*,\K$/filled_last_field/r;
}
# Move $new_file to $file
我使用过/r
modifier的地方,它返回修改后的字符串,就在这里print
的正确位置。有关此类完整程序的详细信息,请参见this post和this post(例如)。
或者,用Path::Tiny
path($file)->edit_lines( sub { s/.*,\K$/ADDED/ } )
在版本0.077中添加了直接编辑文件的方法。该模块的许多方法都有它们的_utf8
对应方法,还有edit_lines_utf8。
一口气
perl -wpe's/.*,\K$/ADDED/' file.csv > new_file.csv
或者,就地更改输入文件
perl -i -wpe's/.*,\K$/ADDED/' file.csv
或者,进行更改并保留备份
perl -i.bak -wpe's/.*,\K$/ADDED/' file.csv