我需要根据第2列的值替换txt文件列中的值。
我有example_data.txt文件:
Name Group Value
ID1 1 1.00
ID2 1 2.00
ID3 1 3.00
ID4 1 4.00
ID5 2 5.00
ID6 2 6.00
......................
ID10 10 7.00
example_values.csv文件,以逗号分隔:
1,6.00
2,7.00
......
10,15.00
替换文件应如下所示:
Name Group Value
ID1 1 6.00
ID2 1 6.00
ID3 1 6.00
ID4 1 6.00
ID5 2 7.00
ID6 2 7.00
......................
ID10 10 15.00
保持字段之间的格式和空格数非常重要。
到目前为止,我已经想出了这个:
#!/usr/bin/perl
use strict;
use warnings;
open(VAL, "<", "example_values.csv") or die $!;
my %hash;
%hash = ( %hash, (split(/,/, $_))) while ( <VAL> );
my $file = '<example_data.txt';
open my $info, $file or die "Could not open $file: $!";
open OUT, ">values_replaced.txt";
my @F = ();
my $k = ();
my %F = ();
while( my $line = <$info>) {
if ($line =~ /ID/) {
my @fields = split " ";
s/$F[1]/%hash($k){$F[0]}/;
print OUT $line;
} else {
print OUT $line;
}
}
close(OUT) || die "Couldn't close OUT properly";
我得到的错误信息是:
Use of uninitialized value $F[1] in regexp compilation at perl.pl line 22, <$info> line 18.
Use of uninitialized value $_ in substitution (s///) at perl.pl line 22, <$info> line 18.
但是OUT文件被写入,它只是输入文件的副本。
我感谢任何帮助,我是perl的新手并且现在真的被困住了。
答案 0 :(得分:4)
看起来这是作业。我将提供一个有效的解决方案和解释,但我希望我不必提醒您,您应该尝试自己解决这个问题,而不是让其他人为您解决。
use strict
和use warnings
非常好:) $fh
)和旧式GLOB文件句柄(OUT
)。只需使用词汇词汇,always use three-argument open就像open my $fh, '<', 'in.csv';
VAL
读取的构造非常 Perlish ,但正如Borodin所指出的那样,它非常低效,因为它会在每次迭代时合并并构造一个新的哈希。我也不确定你是否可以解释它。如果您想购买花哨的Perl内容,请改用map
。它更容易解释它的作用。 ;)close ... || die
可能会有效,但您应该使用or
。它们是有区别的。 and
和or
不太粘性。这称为优先级。请参阅perlop here和here。$k
或@F
不是%F
和@F
用于Perl,但你肯定会混淆它。while
循环中,您split
ting为另一个变量,并且您使用$_
作为split
的输入。但是因为你在循环的头部分配了$line
,那就是undef
。undef
个字段。尝试使用Data::Dumper或更好Data::Printer来输出@fields
s///
的替换部分语法无效。它将尝试替换为括号中'%hash(){}'
警告的文字undef
,因为$k
为空,而undef
因$F[0]
而发出$_
警告$line
else
,因此您可以跳过$line
并在循环后打印close
,无论是否已被替换use strict;
use warnings;
use autodie; # always die when open fails
# Slurp the mapping. This works on $_ and returns a list
# that ends up in the hash.
open my $fh_values, "<", "scratch/example_values.txt";
my %group_value_map = map { chomp; split /,/; } (<$fh_values>);
close $fh_values;
open my $fh_out, '>', '...';
my $file = 'scratch/example_data.txt';
open my $fh_in, '<', $file;
while ( my $line = <$fh_in> ) {
if ( $line =~ /ID/ ) {
# split in " " discards preceeding whitespace and splits
# on arbitrary long whitespace sequences (but only if you
# use it on the right variable)
my @fields = split " ", $line;
# This replacement works nicely now, but will break horribly
# in case an additional column is added :)
$line =~ s/$fields[2]/$group_value_map{$fields[1]}/;
}
# since we modified $line we don't need an else block that prints the
# same value as the last line of the then block
print $line;
}
close $fh_in;
close $fh_out;
你的文件句柄,但要保持一致并关闭所有这些文件Name Group Value
ID1 1 6.00
ID2 1 6.00
ID3 1 6.00
ID4 1 6.00
ID5 2 7.00
ID6 2 7.00
ID10 10 15.00
<强>输出:强>
public static void NotifyAboutNewJob(int jobId, bool forceSending = false)
{
Action<int> notifier = SendAppleNotifications;
notifier.BeginInvoke(jobId, null, null);
}