在perl中进行格式化后,读取一个csv文件并写入另一个csv文件
我试图在perl中操作csv 输入csv在列数据中有一些新行字符,这导致其他外部程序失败。我在下面编写了Perl脚本,对csv进行预处理以删除这些字符在perl中进行格式化后,读取一个csv文件并写入另一个csv文件,csv,perl,Csv,Perl,我试图在perl中操作csv 输入csv在列数据中有一些新行字符,这导致其他外部程序失败。我在下面编写了Perl脚本,对csv进行预处理以删除这些字符 use strict; use warnings 'all'; # Using Text::CSV file to allow # full CSV Reader and Writer use Text::CSV; use open ":std", ":encoding(UTF-8)"; my $file = $ARGV[0] or d
use strict;
use warnings 'all';
# Using Text::CSV file to allow
# full CSV Reader and Writer
use Text::CSV;
use open ":std", ":encoding(UTF-8)";
my $file = $ARGV[0] or die;
my $csv = Text::CSV->new (
{
binary => 1,
auto_diag => 1,
sep_char => ', '
});
my $sum = 0;
# Reading the file
open(my $data, '<:encoding(utf8)', $file) or die;
while (my $words = $csv->getline($data))
{
tr/\r\n//d for @$words; #removing new lines
tr/,/;/ for @$words; #replacing comma with semicolon
$csv->combine(@$words);
print $csv->string, "\n";
}
# Checking for End-of-file
if (not $csv->eof)
{
$csv->error_diag();
}
close $data;
我希望可以在perl脚本本身中使用out csv处理程序将输出写入另一个文件。我尝试了两种方法,但总是出现这样或那样的错误。下面是我试过的东西
my $outcsv = Text::CSV->new ( { binary => 1, quote_char => "", escape_char => "\\" } );
open(my $data, '<:encoding(utf8)', $file) or die;
open(my $fh, ">:encoding(utf8)", "new.csv") or die " new.csv: $!";
while (my $words = $csv->getline($data))
{
tr/\r\n//d for @$words;
tr/,/;/ for @$words;
$csv->combine(@$words);
# Open a handle to the file "new.csv"
$outcsv->print ($fh, $_) for @words;
#print $csv->string, "\n";
}
# Checking for End-of-file
if (not $csv->eof)
{
$csv->error_diag();
}
close $data;
close $fh or die "new.csv: $!";
这是我在上面发布的第一个代码,但为了编写文件,我使用了shell包装器。现在,我只发布了与第一个不同的第二个perl脚本,当我运行它时,它失败并出现错误。我理解这个错误,但不确定如何修复它。全局符号@words需要在xyz.pl第29行显示包名。由于编译错误,xyz.pl的执行被中止。
如果有人能帮忙,我会非常感激的
谢谢通过您的操作系统软件包管理器或喜爱的CPAN客户端安装的模块可以轻松转换CSV文件:
#!/usr/bin/env perl
use strict;
use warnings;
use Text::AutoCSV;
Text::AutoCSV->new(in_file => $ARGV[0],
out_file => $ARGV[1],
encoding => "UTF-8",
has_headers => 1, # Set to 0 if no header line
read_post_update_hr => \&normalize)->write();
sub normalize {
my $hr = shift;
for (values %$hr) {
s/\r?\n//g;
tr/,/;/;
}
}
例如:
$cat input.csv
id,消息
1,一个字符串,带逗号
2,另一个
换行
3,废话
$perl demo.pl input.csv new.csv
$cat new.csv
id,消息
1、一串;用逗号
2,另一个有换行符
3,废话
通过操作系统软件包管理器或喜爱的CPAN客户端安装的模块可轻松转换CSV文件:
#!/usr/bin/env perl
use strict;
use warnings;
use Text::AutoCSV;
Text::AutoCSV->new(in_file => $ARGV[0],
out_file => $ARGV[1],
encoding => "UTF-8",
has_headers => 1, # Set to 0 if no header line
read_post_update_hr => \&normalize)->write();
sub normalize {
my $hr = shift;
for (values %$hr) {
s/\r?\n//g;
tr/,/;/;
}
}
例如:
$cat input.csv
id,消息
1,一个字符串,带逗号
2,另一个
换行
3,废话
$perl demo.pl input.csv new.csv
$cat new.csv
id,消息
1、一串;用逗号
2,另一个有换行符
3,废话
我不确定你在第一个程序中失败了什么,但这里有点简化和清理
use strict;
use warnings 'all';
use Text::CSV;
use open ":std", ":encoding(UTF-8)";
my $file = $ARGV[0] or die "Usage: $0 filename\n";
my $csv = Text::CSV->new({ binary => 1, auto_diag => 1 });
open my $data, '<', $file or die $!;
open my $fh_out, '>', 'new_'.$file or die $!;
while (my $words = $csv->getline($data))
{
tr/\r\n//d for @$words;
tr/,/;/ for @$words;
$csv->say($fh_out, $words);
}
我将它们保留为两个循环,以指示单独的处理步骤
上面使用的say in Text::CSV方法是在某个时候添加到模块中的,比该方法旧的版本不会有它。那就可以了
使用print方法,并在构造函数中设置eol以打印换行符
my $csv = Text::CSV->new ( { binary => 1, auto_diag => 1, eol => $/ });
...
$csv->print($fh_out, $words);
还有其他方法可以获得换行符,请参见文档
或者,不要弄乱构造函数,而是手动添加换行符
$csv->print($fh_out, $words);
print $fh_out "\n";
或者,使用迂回的方式
$csv->combine(@$words);
print $fh_out $csv->string, "\n";
请参阅文档我不确定您在第一个程序中失败了什么,但在这里它有点简化和清理
use strict;
use warnings 'all';
use Text::CSV;
use open ":std", ":encoding(UTF-8)";
my $file = $ARGV[0] or die "Usage: $0 filename\n";
my $csv = Text::CSV->new({ binary => 1, auto_diag => 1 });
open my $data, '<', $file or die $!;
open my $fh_out, '>', 'new_'.$file or die $!;
while (my $words = $csv->getline($data))
{
tr/\r\n//d for @$words;
tr/,/;/ for @$words;
$csv->say($fh_out, $words);
}
我将它们保留为两个循环,以指示单独的处理步骤
上面使用的say in Text::CSV方法是在某个时候添加到模块中的,比该方法旧的版本不会有它。那就可以了
使用print方法,并在构造函数中设置eol以打印换行符
my $csv = Text::CSV->new ( { binary => 1, auto_diag => 1, eol => $/ });
...
$csv->print($fh_out, $words);
还有其他方法可以获得换行符,请参见文档
或者,不要弄乱构造函数,而是手动添加换行符
$csv->print($fh_out, $words);
print $fh_out "\n";
或者,使用迂回的方式
$csv->combine(@$words);
print $fh_out $csv->string, "\n";
请参阅文档,以下是导致问题的代码:
while (my $words = $csv->getline($data))
{
tr/\r\n//d for @$words;
tr/,/;/ for @$words;
$csv->combine(@$words);
# Open a handle to the file "new.csv"
$outcsv->print ($fh, $_) for @words;
#print $csv->string, "\n";
}
在评论中,您给了我们一个错误:
全局符号@words需要在d2l_preprocess_csv_files.pl第29行显示包名
我猜第29行是:
$outcsv->print ($fh, $_) for @words;
对getline的调用为您提供了一个数组引用,该数组引用存储在$words中。如果你想把它当作一个数组,你需要去引用它@$words,就像你在一些地方做的那样。因此,在有问题的一行中,您刚刚忘记了美元。您没有名为@words的数组,您需要使用$@words。以下是导致问题的代码:
while (my $words = $csv->getline($data))
{
tr/\r\n//d for @$words;
tr/,/;/ for @$words;
$csv->combine(@$words);
# Open a handle to the file "new.csv"
$outcsv->print ($fh, $_) for @words;
#print $csv->string, "\n";
}
在评论中,您给了我们一个错误:
全局符号@words需要在d2l_preprocess_csv_files.pl第29行显示包名
我猜第29行是:
$outcsv->print ($fh, $_) for @words;
对getline的调用为您提供了一个数组引用,该数组引用存储在$words中。如果你想把它当作一个数组,你需要去引用它@$words,就像你在一些地方做的那样。因此,在有问题的一行中,您刚刚忘记了美元。您没有名为@words的数组,您需要使用$@words。如果您在此处发布示例数据,将不胜感激。另外,请告诉我们failsok是什么以及如何工作的,我发布的第一个代码,但为了编写文件,我使用了shell包装器。现在,我发布的第二个perl脚本的代码与第一个不同,当我运行它时,它失败了,错误如下。我理解错误,但不确定如何修复全局符号@words需要在d2l_preprocess_csv_files.pl第29行显示包名。由于编译错误,d2l_preprocess_csv_files.pl的执行已中止。好的,谢谢你的回复。这类信息需要在问题开始。示例:我马上发现你的第二个程序中有一个@words,我想这是发帖时的一个输入错误,你不小心掉了那美元。但是一旦你显示了错误,我们知道这实际上是个问题。如果你在这里发布示例数据,我们将非常感激。另外,请告诉我们failsok是什么以及如何工作的,我发布的第一个代码,但我使用了shell包装器来编写文件。
现在,我发布的第二个perl脚本的代码与第一个不同,当我运行它时,它失败了,错误如下。我理解错误,但不确定如何修复全局符号@words需要在d2l_preprocess_csv_files.pl第29行显示包名。由于编译错误,d2l_preprocess_csv_files.pl的执行已中止。好的,谢谢你的回复。这类信息需要在问题开始。示例:我马上发现你的第二个程序中有一个@words,我想这是发帖时的一个输入错误,你不小心掉了那美元。但一旦你显示了错误,我们就知道这实际上是个问题。谢谢@zdim!我的第一个程序运行良好,但正如我所说,它不会写入文件,而是写入标准输出。我的第二个程序失败了。我在上面的评论中给出了错误消息。我会测试你的方法,让你知道我的进展。嗨@zdim。当我运行上面的程序时,它会给我一个错误。无法在xyz.pl第18行找到方法say。我的perl版本是Perl5,版本16,Subversion3V5.16.3,是为x86_64-linux-thread构建的-multi@giri啊,这意味着您的Text::CSV比他们介绍的任何时候都要旧,比如说它是在某一点上添加的。然后用他们的指纹instead@giri但是我有相同的Perl,我的Text::CSV版本1.33说…?@giri在回答的末尾添加了选项谢谢@zdim!我的第一个程序运行良好,但正如我所说,它不会写入文件,而是写入标准输出。我的第二个程序失败了。我在上面的评论中给出了错误消息。我会测试你的方法,让你知道我的进展。嗨@zdim。当我运行上面的程序时,它会给我一个错误。无法在xyz.pl第18行找到方法say。我的perl版本是Perl5,版本16,Subversion3V5.16.3,是为x86_64-linux-thread构建的-multi@giri啊,这意味着您的Text::CSV比他们介绍的任何时候都要旧,比如说它是在某一点上添加的。然后用他们的指纹instead@giri但是我有相同的Perl,我的Text::CSV版本1.33说…?@giri在回答的末尾添加了选项谢谢Shawn!我将查看服务器中是否已安装此模块。如果尚未安装,我恐怕无法尝试。谢谢Shawn!我将查看服务器中是否已安装此模块。如果尚未安装,我恐怕无法尝试。嗨,戴夫,谢谢你的回复。尝试了您的建议,但仍然收到一个错误,预期字段在xyz.pl第29行,第1行是数组引用。@giri:我的修复程序将停止您报告的初始错误。如果看不到当前代码的样子,很难提供更多帮助。嗨,Dave,谢谢你的回复。尝试了您的建议,但仍然收到一个错误,预期字段在xyz.pl第29行,第1行是数组引用。@giri:我的修复程序将停止您报告的初始错误。如果看不到当前代码的样子,很难提供更多的帮助。