Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/perl/9.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Perl读取文件并将每行存储为变量/值_Perl_File_Variables - Fatal编程技术网

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

我对perl还很陌生,但到目前为止,我几乎做了所有我需要做的事情

我有一个格式如下的文件:

#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-arg
open
;检查
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{$_});
}