哈希中的键问题

时间:2013-12-12 12:24:46

标签: perl file hash key

将脚本从Windows机器移动到Unix系统后,我遇到了一个非常奇怪的问题。 我已经编写了READIN子程序并在Windows上使用Perl 5.16.3成功测试了它,但它在使用Perl 5.14.2的Unix下无法运行

sub READIN
{
my (%tmp, $val, $key);
open (DAT, "$_[0]")or die "Thou shalt not open this file, so I generated an error: $! \n";
while (<DAT>)
    {
    chomp;
    ($val, $key) = split (/;/);
    #print "Value -> $val - Key_for_Hash -> $key\n"; *#DBG - Works!*

    $tmp{$key} = exists $tmp{$key}? "$val" : $val;

    #print "ValueH -> $tmp{$key} - Key_for_HashH -> $key\n"; *#DBG - Works!*

    #print "KeyH-> $key - ValueH -> $tmp{$key}\n"; *#DBG - doesn't work, cuts of everything before " - ValueH....."*

    #print "Value2 -> $val - Key_for_Hash2 -> $key\n\n";*#DBG - Works!*

    }
close DAT or die "Filehandle is grumpy today and dislikes your Idea to be closed as of $\n";
return %tmp;
}

我使用Data :: Dumper获得的输出是:

    $VAR1 = {
' => '18.15.7.1.39.',
' => '19.15.7.1.39.',
' => '19.15.9.1.6.1.',
' => '19.15.7.1.6.',
' => '19.15.1.',
' => '18.15.1.',
' => '18.15.7.1.36.',
' => '18.15.7.1.34.',
' => '18.15.7.1.1.',
' => '18.15.7.1.33.',
' => '18.1.9.0',
' => '19.15.7.1.36.',
' => '16.15.2.1.4.1',
' => '18.15.7.1.38.',
' => '19.15.9.1.13.',
' => '18.15.9.1.6.1.',
' => '16.1.9.0',
' => '19.15.7.1.33.',
' => '19.15.7.1.37.',
' => '19.1.9.0',
' => '19.15.9.1.3.',e
' => '19.15.7.1.4.',
' => '19.15.7.1.38.',
' => '19.15.7.1.34.',
          'radioid2e' => '19.15.7.1.1.',
' => '16.15.2.1.4.1',
' => '19.15.7.1.35.',
' => '18.15.7.1.35.'
        };

最后,这是我从文件中读取的数据:

16.1.9.0;去掉
16.15.2.1.4.1; KAP
16.15.2.1.4.1; MOD
18.1.9.0; RID2
18.15.7.1.35; tdmkapt2
18.15.7.1.38; tdmkapr2
18.15.7.1.34; modt2
18.15.7.1.33; modr2
18.15.9.1.6.1; tdmkap2
18.15.7.1.36; etht2
18.15.7.1.39; ethr2
18.15.1; RT2
18.15.7.1.1; radioid2
19.1.9.0; rid2e
19.15.7.1.35; tdmkapt2e
19.15.7.1.38; tdmkapr2e
19.15.7.1.34; modt2e
19.15.7.1.33; modr2e
19.15.9.1.6.1; tdmkap2e
19.15.7.1.36; etht2e
19.15.7.1.39; ethr2e
19.15.1; rt2e
19.15.7.1.4; um2e
19.15.7.1.37; lm2e
19.15.9.1.3; glokapam2e
19.15.9.1.13; ethkapam2e
19.15.7.1.6; acmcpm
19.15.7.1.1; radioid2e

有人可以指出我做错了什么吗?或者它是5.14.6的一般问题?

//编辑:

这是我在Windows中获得的Data :: Dumper输出(Perl 5.16.3):

$VAR1 = {
      'rid2e' => '19.1.9.0',
      'rt2' => '18.15.1.',
      'ethkapam2e' => '19.15.9.1.13.',
      'etht2' => '18.15.7.1.36.',
      'etht2e' => '19.15.7.1.36.',
      'tdmkapt2e' => '19.15.7.1.35.',
      'tdmkapr2' => '18.15.7.1.38.',
      'tdmkapt2' => '18.15.7.1.35.',
      'ethr2' => '18.15.7.1.39.',
      'ethr2e' => '19.15.7.1.39.',
      'tdmkap2e' => '19.15.9.1.6.1.',
      'acmcpm' => '19.15.7.1.6.',
      'rt2e' => '19.15.1.',
      'modt2e' => '19.15.7.1.34.',
      'modr2e' => '19.15.7.1.33.',
      'um2e' => '19.15.7.1.4.',
      'radioid2' => '18.15.7.1.1.',
      'tdmkap2' => '18.15.9.1.6.1.',
      'rid' => '16.1.9.0',
      'modr2' => '18.15.7.1.33.',
      'glokapam2e' => '19.15.9.1.3.',
      'rid2' => '18.1.9.0',
      'kap' => '16.15.2.1.4.1',
      'tdmkapr2e' => '19.15.7.1.38.',
      'radioid2e' => '19.15.7.1.1.',
      'modt2' => '18.15.7.1.34.',
      'mod' => '16.15.2.1.4.1',
      'lm2e' => '19.15.7.1.37.'
    };

1 个答案:

答案 0 :(得分:5)

看起来你的\r\n行结尾了。您可以尝试使用

而不是chomp
s/[\r\n]+$//g;

从其他操作系统(如Windows)导入文件时,这是一个常见问题。 chomp命令从行尾删除本机换行符(包含在变量$/中)。在linux中,这将是\n,但在Windows中它是\r\n。因此,在linux中,您读取了一行\n,删除\n\r将光标重置为行首,以便覆盖行的开头。

实际上,这主要是一个视觉问题(除了字符串中有垃圾\r字符)。如果你添加

$Data::Dumper::Useqq = 1;

到您的代码中,您会看到以纯文本打印的\r字符,如下所示:

"ethr2\r" => "18.15.7.1.39.",

您还应该了解以下内容:

  • 始终使用use strict; use warnings;。它将比你在代码中使用的任何其他东西更有帮助,并且学习使用它们并不困难。
  • $tmp{$key} = exists $tmp{$key}? "$val" : $val;不执行任何操作,因为"$val"$val相同。如果您有use warnings,如果密钥不存在且警告Use of uninitialized value $val in string
  • ,它会发出警告
  • 由于您不太可能要分割超过2次,因此您可以对分割使用限制:split /;/, $_, 2;