perl-用哈希替换字段值
我需要根据第2列的值替换txt文件列中的值 我有示例_data.txt文件:perl-用哈希替换字段值,perl,Perl,我需要根据第2列的值替换txt文件列中的值 我有示例_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 和示例_values.csv文件,以逗号分隔: 1,6.
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
和示例_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";
#/usr/bin/perl
严格使用;
使用警告;
打开(VAL,“values_replaced.txt”;
我的@F=();
我的$k=();
我的%F=();
while(我的$line=){
如果($line=~/ID/){
我的@fields=split”“;
s/$F[1]/%hash($k){$F[0]}/;
打印$line;
}否则{
打印$line;
}
}
关闭(关闭)| |模具“无法正确关闭”;
我收到的错误消息是:
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.
在perl.pl第22行、第18行的regexp编译中使用未初始化值$F[1]。
在perl.pl第22行、第18行的替换(s//)中使用未初始化的值$。
但输出文件是编写的,它只是输入文件的副本
非常感谢您的帮助,我对perl还不太熟悉,现在真的被卡住了。看起来这是家庭作业。我将提供一个有效的解决方案和解释,但我希望我不必提醒您,您应该自己解决这个问题,而不是让其他人帮您解决
- 很好,您有
使用严格的
和
使用警告
:)
- 您正在混合词法文件句柄(
)和旧式全局文件句柄($fh
)。只需使用词法,就像OUT
打开我的$fh,“看起来这是家庭作业。我将提供一个有效的解决方案和解释,但我希望我不必提醒您,您应该尝试自己解决这个问题,而不是让其他人为您解决
- 很好,您有
使用严格的
和
使用警告
:)
- 您正在混合词法文件句柄(
)和旧式全局文件句柄($fh
)。只需使用词法,像打开我的$fh一样,初始化OUT
@F=()代码>,则决不向阵列分配/推送任何其他内容。您希望在
中找到什么价值?您希望它是如何实现的?您显然使用了大量不同的源代码。这里有几个问题。$F[1]
应该做什么?类表文件选项卡是否被分隔?您应该在类$k
的纯文字文件句柄和类VAL
的词法文件句柄之间进行选择,并坚持使用。不要把它们混在一起。(你的选择应该是词法句柄。)你初始化$info
@F=()代码>,则决不向阵列分配/推送任何其他内容。您希望在
中找到什么价值?您希望它是如何实现的?您显然使用了大量不同的源代码。这里有几个问题。$F[1]
应该做什么?类表文件选项卡是否被分隔?您应该在类$k
的纯文字文件句柄和类VAL
的词法文件句柄之间进行选择,并坚持使用。不要把它们混在一起。(你的选择应该是词法句柄。)“你用来从VAL读取的构造很好”我不会说得那么好。我能提供$info
可替换为split/\s+/;如果…
拆分,则移位代码>-它默认为
作为分隔符,跳过前导空格。@sob继续。我在打电话。改变它:-)@Borodin我改变了那个短语。你说得对,我不清楚。谢谢你。@Sobrique谢谢你修改它。下次再更新评论时,它不适合您的编辑;-)“你用来阅读VAL的结构很好”我不会说得那么好。我能提供'
可替换为split/\s+/;如果…
拆分,则移位代码>-它默认为
作为分隔符,跳过前导空格。@sob继续。我在打电话。改变它:-)@Borodin我改变了那个短语。你说得对,我不清楚。谢谢你。@Sobrique谢谢你修改它。下次再更新评论时,它不适合您的编辑;-)'
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
- 很好,您有