我有一个很大的文件(19M行),并且需要清理数据。我使用的是Windows 11机器。数据正在加载到SQL Server 19中。我目前正在使用Perl脚本删除双引号之间的逗号。我将在下面发布我的脚本。这需要很长时间才能运行。我觉得powershell会更快,但是我似乎不能让它运行我需要的REGEX。
#! /usr/bin/perl -w
use strict;
use warnings;
my $SRC = $ARGV[0];
my $DES = $ARGV[1];
open(SRC,'<',$SRC) or die $!;
open(DES,'>',$DES) or die $!;
my $n_fields = "";
while (<>) {
s/\s+$//;
if (/^\#/) { # header line
my @t = split(/,/);
$n_fields = scalar(@t); # total number of fields
} else { # actual data
my $n_commas = $_ =~s/,/,/g; # total number of commas
foreach my $i (0 .. $n_commas - $n_fields) { # iterate ($n_commas - $n_fields + 1) times
s/(\"[^",]+),([^"]+\")/$1\"$2/g; # single replacement per previous answers
}
s/\"//g; # removal of double quotes (if you want)
}
print DES "$_\n";
}
close (DES);
close (SRC);
我上面提供的代码可以工作,但是非常非常慢。正在寻找一种更快的方法来处理数据。比你提前。
2条答案
按热度按时间voj3qocg1#
我接的任务是:删除引号下的逗号,并删除引号。(因此,请清除CSV文件中多余的逗号并删除引号。)
对于初学者来说,这里有一些基于正则表达式的精简代码。我希望这比OP代码快得多。请提供一个示例输入(和/或时间代码)以进行改进。请注意清楚地采取的假设。
我们始终建议使用库(如Text::CSV,请参见here示例),但在这种情况下可能不会更快。(需要实际的样本来对CSV库进行基准测试。)†
[2]在等待一个现实的样本时,这里有一个基准。
我通过重复1,000次并打乱行来创建一个输入文件:
然后在其上运行一个程序
如果您的输入使用了松散的引号,使
some "then quoted" more
之类的字段而不是整个字段被引用,则使用allow_loose_quotes属性。通过运行
program.pl input.csv 30
(每个测试运行30秒),我得到,在一个旧的笔记本电脑与v5.16(在5.36.0版本的服务器上几乎相同,速率大约是5.36.0版本的两倍。)
如果你的情况也是如此,并且regex不能得到实质性的改进,那么我强烈建议你使用CSV库的代码。CSV库的正确性和处理一系列意外/坏的CSV属性的能力远比20%的速度改进更有价值。
然后,至少对于非常大的文件,不要在数组中收集行(
push @lines, join ',', @$row;
),而是在它们出现时打印它们(say join ',', @$row;
)。ymdaylpp2#
这看起来像是您创建了一个无限循环,在阅读文件的同时写入文件。
将
while (<>)
更改为while (<SRC>)
,看看会发生什么情况。可能还要检查输出文件的文件大小,以确认是否存在表示无限循环的大文件。