哈希中的键问题

0 perl hash file 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;
}
Run Code Online (Sandbox Code Playgroud)

我用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.'
        };
Run Code Online (Sandbox Code Playgroud)

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

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.'
    };
Run Code Online (Sandbox Code Playgroud)

TLP*_*TLP 5

看起来你有一条\r\n线在那里结束.而不是chomp,您可以尝试使用

s/[\r\n]+$//g;
Run Code Online (Sandbox Code Playgroud)

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

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

$Data::Dumper::Useqq = 1;
Run Code Online (Sandbox Code Playgroud)

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

"ethr2\r" => "18.15.7.1.39.",
Run Code Online (Sandbox Code Playgroud)

您还应该了解以下内容:

  • 总是用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;