在行尾之前填写空数据

时间:2018-06-25 22:24:38

标签: perl pcre

我正在处理一些CSV文件。最后一个字段有时会丢失数据,如下所示: first,last John,Smith Francis,

这在尝试加载到数据库中时导致提取错误。我想在crlf之前的最后一个逗号之后添加一个空格或其他“填充符”,但是我很难用搜索/替换填充它。我已经尝试了以下示例: $data =~ s/,\x0d\x0a/,\x20\x0d\0xa/gi,但在crlf之前没有添加空格。 当然,我需要保留行尾,以便正确标记行。

我尝试使用Path :: Tiny和通用open进行阅读,但到目前为止没有成功。

1 个答案:

答案 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 postthis 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