Perl读取文件并将每行存储为变量/值
我对perl还很陌生,但到目前为止,我几乎做了所有我需要做的事情 我有一个格式如下的文件:Perl读取文件并将每行存储为变量/值,perl,file,variables,Perl,File,Variables,我对perl还很陌生,但到目前为止,我几乎做了所有我需要做的事情 我有一个格式如下的文件: #IPAAS @NX_iPaaS_AuthKey=dGstaG9zaGlub0BqcCasdpasdHN1LmNvbTppUGFhUzAw @NX_iPaaS_href=live/661134565/process/75231 我想把以@NX_iPaaS开头的每一行读入一个类似的命名变量,例如。 @NX_iPaaS_AuthKey将创建一个名为$NX_iPaaS_AuthKey的新变量并保存该值,NX
#IPAAS
@NX_iPaaS_AuthKey=dGstaG9zaGlub0BqcCasdpasdHN1LmNvbTppUGFhUzAw
@NX_iPaaS_href=live/661134565/process/75231
我想把以@NX_iPaaS开头的每一行读入一个类似的命名变量,例如。
@NX_iPaaS_AuthKey将创建一个名为$NX_iPaaS_AuthKey的新变量并保存该值,NX_iPaaS_href将生成一个名为$NX_iPaaS_href的新变量,并带有一个值,依此类推
--更新--
嘿,伙计们,我需要一个轻微的调整需要上述解决方案
所以我刚刚发现我正在阅读的文件将有“节”,例如
----- SECTION=cr
NX_NTF_PERSISTENT_ID=cr:400017
NX_NTF_REF_NUM=45
----- SECTION=cnt
NX_NTF_PERSISTENT_ID=cnt:F9F342055699954C93DE36923835A182
您可以看到其中一个变量出现在两个部分中,这(因为我没有“next除非已定义”)会导致覆盖上一个值。是否有一种方法可以在NX_NTF_u变量名前面加上每个节顶部“section=”行中提供的值
谢谢好的做法是使用哈希
my %hash;
while (<>) {
chomp;
my ($key, $value) = split /=/;
next unless defined $value;
$hash{$key} = $value;
}
my%hash;
而(){
咀嚼;
我的($key,$value)=拆分/=;
下一步,除非定义$value;
$hash{$key}=$value;
}
请参阅为什么使用变量名不是一个好主意。您要使用的是哈希。比如:
use strict;
use warnings;
my $input = "yourfilename.txt";
open(my $IN, "<", $input) or die "$0: Can't open input file $input: $!\n";
my %NX_iPaaS_vars;
while (<$IN>) {
chomp;
if ($_ =~ /^\@NX_iPaaS/) {
my ($key, $value) = split(/=/, $_);
$NX_iPaaS_vars{$key} = $value;
}
}
#/usr/bin/perl-w
严格使用;
打开(文件“test.txt”);
我的%hash;
foreach()
{
如果($\=~/@(\S+)=(\S+/)
{
$hash{$1}=$2;
}
}
关闭(文件);
#测试代码
foreach(键%hash)
{
printf(“%s=%s\n”,$\u,$hash{$\u});
}
如果变量名是唯一的,这个解决方案效果很好。简单状态机:读取一行,找出它是什么,然后将它存储到相应的位置。起泡,冲洗,重复。你不想那样做。用散列代替。任何例子都很好。。。我已经做了6个小时了,一整天都在复制粘贴代码,但是没有用……:)不要使用
-w
;缺少使用警告
;不要使用裸字文件句柄;不要使用2-argopen
;检查open
的返回值是否存在错误;不要使用foreach()
;避免
<代码>$\u9=~是冗余的<代码>\S+可能匹配=
(即您的正则表达式可能错误);如果没有充分的理由,不要使用printf
。为什么不使用-w?那printf呢?为什么$冗余?@Jean当您使用警告时
,您可以有选择地禁用某些警告类别,例如无警告“重新定义”
。使用此开关而不是-w
开关被视为最佳做法。Perl字符串可以插入变量<代码>打印“$\=$hash{$\}\n”是等效的,具有较少的间接性。当您需要高级格式化(以特定长度切割字符串、对齐、舍入、十六进制…)时,请使用printf
。如果正则表达式未通过=~
绑定,则默认情况下,它与主题变量$\uu
匹配for()
一次读取所有行;`while()`一次一行。您的意思是regex/^@([^=]+)=(.*)$/
谢谢..您能举一个我的regex失败的例子吗?@Jean问题是可能包含=
的值。例如,使用email=hello=world@example.com
您的正则表达式将email=hello
视为字段名和world@example.com
作为值。这通常不是用户所期望的。uptownnickbrown,感谢您的示例,但这会引发一个错误:在iPaaS2.pl第11行的字符串中可能意外插入@NX_iPaaS。iPaaS2.pl第9行靠近“{”全局符号“@NX_iPaaS”的语法错误要求在iPaaS2.pl第11行有显式的包名。iPaaS2.pl第15行靠近“}”的语法错误由于编译错误而中止了iPaaS2.pl的执行。抱歉,我只是在SO中抛出了它,没有进行测试。有人刚刚编辑过,@需要在第11行的正则表达式中转义,如:\@。啊,第6行还有一个缺少的右括号,(){很乐意帮忙。你应该真正阅读choroba链接到的文章-很好地解释了为什么你应该用散列来解决这个问题。
my $href_path = $NX_iPaaS_vars{'@NX_iPaaS_href'};
# Do something with $href_path here...
#!/usr/bin/perl -w
use strict;
open(FILE,"test.txt");
my %hash;
foreach (<FILE>)
{
if($_=~/@(\S+)=(\S+)/)
{
$hash{$1}=$2;
}
}
close(FILE);
# Test Code
foreach (keys %hash)
{
printf("%s=%s\n",$_,$hash{$_});
}