我需要处理许多文件(以CRLF行结尾),看起来像这样:
$ cat -v file1.txt
1$XXX$ZZZ$$$$$$$$^M
2$AAA$BBB$$$$$$$$^M
$ cat -v file2.txt
1$4668$$$^M
2$46$$$^M
我需要:
- 删除最后一个
$
符号, - 将所有
$
更改为,
, - 用双引号将每个字段括起来,
- 重命名文件。
所需输出:
$ cat -v newname1.csv
"1","XXX","ZZZ","","","","","","",""^M
"2","AAA","BBB","","","","","","",""^M
$ cat -v newname2.csv
"1","4668","",""^M
"2","46","",""^M
以下是我的尝试:
#!/usr/bin/perl
use strict;
use warnings;
my %inputs = qw(
file1 file1.txt
file2 file2.txt
);
my %outputs = qw(
file1 newname1.csv
file2 newname2.csv
);
for my $key (keys %inputs) {
open my $in, '<', $inputs{$key} or die $!;
open my $out, '>', $outputs{$key} or die $!;
while(<$in>) {
local $, = ',';
local $\ = "\n";
s/\$$//;
my @row = split /\$/;
print $out map qq("$_"), @row;
}
close $in or die $!;
close $out or die $!;
}
它给出了在最后一列中包含一个新行的文件:
$ cat -v newname1.csv
"1","XXX","ZZZ","","","","","","","","^M
"^M
"2","AAA","BBB","","","","","","","","^M
"^M
$ cat -v newname2.csv
"1","4668","","","^M
"^M
"2","46","","","^M
"^M
我猜这个问题是由于CRLF行结束。因此,我尝试:
- 将
'<'
更改为'<:crlf'
以打开我的文件,结果相同; - 使用其他正则表达式来匹配最后一个
$
符号(例如\$\r\n
和\$\R
,它们都导致文件没有空的尾随列)。
我如何修复我的代码以获得我想要的输出?
1条答案
按热度按时间mjqavswn1#
更新:这个答案是为前两个版本的问题写的。我只是因为OP要求我删除它。它可能不适合当前版本的问题。有些事情可能是完全错误的。
这与行结束符是CRLF无关。这只是一个
split
问题。如果我在代码中添加一个Dumper打印,其中您已拆分为变量
@row
我得到(对于第一个字段):
在分割的最后一个字段中可以看到尾随的换行符。
然后,当您将这些拆分结果视为数据中的真正列值时,将为换行符添加1个字段。
我看不出你在哪里删除了最后一个
$
。也许这是你误解了什么?建议方案:
如果这是csv数据,您应该使用csv模块来处理它。
Text::CSV
模块可以很好地完成此操作。下面是一个处理您的输入的示例代码:更新:
自从你编辑了你的问题并添加了一行代码,改变了 * 一切 * 并使你自己声称的输出“错误”,我发现了以下内容:
如果您只有尾随的空字段,
split
将默认删除这些空字段。这可以修复,如documentation for split中所指定的:如果LIMIT是负的,则它被视为任意大的;产生尽可能多的场。
如果LIMIT被省略(或者,等价地,零),则它通常被视为好像它是负的,但是例外的是尾部空字段被剥离(空的前导字段总是被保留);如果所有字段都是空的,则所有字段都被认为是拖尾的(并且因此在这种情况下被剥离)。
换句话说,你可以改变
到
以修复丢失的尾随空字段。
唯一的问题是你还没有报告有这个问题(还没有)。所以,我想我们需要等待你更新你的问题。