【问题标题】:Extraction and printing of key-value pair from a text file using Perl使用 Perl 从文本文件中提取和打印键值对
【发布时间】:2013-09-24 21:38:40
【问题描述】:

我有一个文本文件 temp.txt,其中包含类似的条目,

cinterim=3534
cstart=517
cstop=622
ointerim=47
ostart=19
ostop=20

注意:键值对可以换行排列,也可以同时排列在一行中,用空格隔开。

我正在尝试使用 Perl 为相应的键打印这些值并将其存储在数据库中。但是我收到了很多错误和警告。现在我只是想打印这些值。

use strict;
use warnings;

open(FILE,"/root/temp.txt") or die "Unable to open file:$!\n";

while (my $line = <FILE>) {
  # optional whitespace, KEY, optional whitespace, required ':', 
  # optional whitespace, VALUE, required whitespace, required '.'
  $line =~ m/^\s*(\S+)\s*:\s*(.*)\s+\./;
  my @pairs = split(/\s+/,$line);
  my %hash = map { split(/=/, $_, 2) } @pairs;

  printf "%s,%s,%s\n", $hash{cinterim}, $hash{cstart}, $hash{cstop};

}
close(FILE);

有人可以提供帮助来完善我的程序吗?

【问题讨论】:

  • 您收到了哪些错误和警告。请在此处展示。
  • 您的脚本不适合您的数据集 - 脚本正在拆分 ':' 上以 '.' 结尾的数据行,但您的数据对由 '=' 分隔,而不是以'.'.

标签: perl search hash extract


【解决方案1】:
use strict;
use warnings;

open my $fh, '<', '/root/temp.txt' or die "Unable to open file:$!\n";
my %hash = map { split /=|\s+/; } <$fh>;
close $fh;
print "$_ => $hash{$_}\n" for keys %hash;

这段代码的作用:

&lt;$fh&gt; 从我们的文件中读取一行,或者在列表上下文中读取所有行并将它们作为数组返回。

map 中,我们使用正则表达式/= | \s+/x 将行拆分为一个数组。这意味着:当您看到= 或一系列空白字符时拆分。这只是您原始代码的精简和美化形式。

然后,我们将map 生成的列表转换为hash 类型。我们可以这样做,因为列表的项目数是偶数。 (此时输入如key key=valuekey=value=value 将引发错误)。

之后,我们打印散列。在 Perl 中,我们可以直接在字符串中插入哈希值,除了特殊格式外,不必使用printf 和朋友。

for 循环遍历所有键(在 $_ 特殊变量中返回),$hash{$_} 是对应的值。这也可以写成

while (my ($key, $val) = each %hash) {
  print "$key => $val\n";
}

each 遍历所有键值对。

【讨论】:

  • 你能补充解释吗?
  • @cdtits:非常感谢,它有帮助。
【解决方案2】:

试试这个

use warnings;

my %data = ();

open FILE, '<', 'file1.txt' or die $!;
while(<FILE>)
{
    chomp;
    $data{$1} = $2 while /\s*(\S+)=(\S+)/g;
}
close FILE;

print $_, '-', $data{$_}, $/ for keys %data;

【讨论】:

    【解决方案3】:

    最简单的方法是将整个文件放入内存并使用正则表达式将键/值对分配给哈希。

    这个程序展示了技术

    use strict;
    use warnings;
    
    my %data = do {
      open my $fh, '<', '/root/temp.txt' or die $!;
      local $/;
      <$fh> =~ /(\w+)\s*=\s*(\w+)/g;
    };
    
    use Data::Dump;
    dd \%data;
    

    输出

    {
      cinterim => 3534,
      cstart   => 517,
      cstop    => 622,
      ointerim => 47,
      ostart   => 19,
      ostop    => 20,
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-11-27
      • 2014-07-14
      • 2011-11-02
      • 1970-01-01
      • 2017-06-16
      相关资源
      最近更新 更多