到目前为止,我想出了如何使用这个perl模块Text::CSV_XS
来匹配csv文件中的一行。
我需要帮助的是删除文件中的那一行。是否有捷径可寻?有没有办法在这个模块中做到这一点?
use strict;
use warnings;
use Text::CSV_XS;
my @rows;
my $csv = Text::CSV_XS->new ({ binary => 1 }) or
die "Cannot use CSV: ".Text::CSV_XS->error_diag ();
open my $fh, "<:encoding(UTF-16LE)", "Test.txt" or die "cannot open file: $!";
while (my $row = $csv->getline ($fh)) {
if ($row->[0] =~ m/ABCDE/)
{
print "We have a match, remove the line \n";
}
else
{
print "No match found\n";
}
}
$csv->eof or $csv->error_diag ();
close $fh;
答案 0 :(得分:2)
答案 1 :(得分:2)
从文件中删除内容的唯一方法是读取文件并写出新内容。执行此操作的常用方法是打开另一个文件进行写入,从输入文件中读取记录,并仅将要保留的记录写入输出文件。然后close两者,unlink或rename原始(取决于您是否要保留备份),然后将rename输出文件添加到原始输入文件名。
答案 2 :(得分:0)
我不确定Text :: CSV_XS是否允许您删除行。我不这么认为
删除线条的一种方法是在while循环中读取线条时,只需存储所需的线条
关闭文件后,只需使用要保留在文件中的所有行覆盖它。
因此,在您的情况下,任何与ABCDE不匹配的内容都应该保存,然后再写回到同一个文件中。
所以你最终会读取10行并写回9(假设有一行有ABCDE)。
答案 3 :(得分:0)
首先,我将解析CSV文件。
use Text::CSV_XS qw( csv );
$parsed_file_array_of_hashesv = csv(
in => "$input_csv_filename",
sep => ';',
headers => "auto"
); # as array of hash
第二,一旦有了 $ parsed_file_array_of_hashesv ,现在您可以在perl中循环该数组并检测要从该数组中删除的行。 然后使用
将其删除拼接阵列,偏移量,长度
从索引OFFSET到索引OFFSET + LENGT删除所有内容
让我们假设索引为0
my @extracted_array = @$parsed_file_array_of_hashesv; #dereference hashes reference
splice @extracted_array, 0, 1;#remove entry 0
$ref_removed_line_parsed = \@extracted_array; #referece to array
第三,将数组写回到CSV文件
$current_metric_file = csv(
in => $ref_removed_line_parsed, #only accepts referece
out => "$output_csv_filename",
sep => ';',
eol => "\n", # \r, \n, or \r\n or undef
#headers => \@sorted_column_names, #only accepts referece
headers => "auto"
);
请注意,如果您使用\ @sorted_column_names,则可以控制列的顺序
my @sorted_column_names;
foreach my $name (sort {lc $a cmp lc $b} keys %{ $parsed_file_array_of_hashesv->[0] }) { #all hashes have the same column names so we choose the first one
push(@sorted_column_names,$name);
}
那应该在没有一行的情况下写CSV文件。