【问题标题】:Issue in Printing data from a hash table in perl从 perl 中的哈希表打印数据的问题
【发布时间】:2018-09-19 07:47:19
【问题描述】:

我正在尝试处理单个文件中的数据。我必须读取文件并创建一个哈希结构,获取fruitname的值将其附加到fruitCount和fruitValue并删除行fruitName并在更改完成后写入整个输出。下面是文件的内容。

 # this is a new file
{
date 14/07/2016
time 11:15
end 11:20
total 30
No    "FRUITS"
Fruit_class
    {
    Name    "fruit 1"
    fruitName    "apple.fru"
    fruitId    "0"
    fruitCount    5
    fruitValue    6
    }
{
        Name    "fruit 2"
        fruitName       "orange.fru"
        fruitId "1"
        fruitCount      10
        fruitValue      20
        }
}

我尝试了以下代码:

#!/usr/bin/perl
use strict;
use warnings;
use Data::Dumper;
my %hash_table;
my $name;
my $file = '/tmp/fruitdir/fruit1.txt';
open my $fh, "<", $file or die "Can't open $file: $!";
while (<$fh>) {
    chomp;
    if (/^\s*fruitName/) {
        ($name) = /(\".+\")/;
        next;
   }
   s/(fruitCount|fruitValue)/$name\.$1/;
   my ($key, $value) = split /\s+/, $_, 2;
   $hash_table{$key} = $value;
}
print Dumper(\%hash_table);

这行不通。我需要附加fruitname 的值并将整个文件内容打印为输出。任何帮助将不胜感激。下面是我得到的输出。

$VAR1 = {
          '' => undef,
          'time' => '11:15    ',
          'date' => '14/07/2016',
          '{' => undef,
          '#' => 'this is a new file',
          'total' => '30    ',
          'end' => '11:20    ',
          'No' => '"FRUITS"',
          'Fruit_class' => undef,
          '}' => undef
        };

预期的哈希作为输出:

$VAR1 = {
          'Name' => '"fruit 1"',
          'fruitId' => '"0"            ',
          '"apple_fru".fruitValue' => '6            ',
          '"apple_fru".fruitCount' => '5'

          'Name' => '"fruit 2"',
          'fruitId' => '"0"            ',
          '"orange_fru".fruitValue' => '10            ',
          '"orange_fru".fruitCount' => '20'


        };

【问题讨论】:

  • 哈希表的用途是什么?如果你只想修改文件中的行,为什么需要它?
  • 是的。您的查询绝对有效。但我的要求要求我在这里使用哈希表概念。我已经使用 shell 脚本实现了输出。但是现在它是用 perl 和哈希概念来完成的。我被这个困住了:(
  • 那么你的问题真的是关于将配置(输入)文件读入哈希吗?然后修改散列,然后将散列打印到文件中?在这种情况下,我建议使用 JSON 而不是自定义的输入文件格式。通过这种方式修改变得容易得多,因为已经存在用于读取和写入 JSON 的模块。
  • 好的。谢谢。我会尝试。但是我可以知道我在上面的代码中哪里出错了吗?只是想知道。
  • 不客气,祝你好运!关于您显示的输出。我认为代码有很多问题。但有一件事是为什么缺少水果信息。我认为这是因为您在空白处拆分,并且带有水果信息的行以至少两个空格开头,所以也许所有这些行都映射到输出中的'' =&gt; undef 行?

标签: perl


【解决方案1】:

在我继续之前的一个忠告:

记录您的代码

你的代码中有几个逻辑错误,如果你写下你认为每一行应该做的事情,我认为你会发现这些错误。首先,写下您想要实现的算法,然后记录代码中的每个步骤如何实现算法中的一个步骤。最后,您将能够看到您错过了什么,或者哪些部分无法正常工作。

这是我看到的错误

  1. 您没有忽略不应解析的行。例如,您正在抓取 '}' 和 '{' 行。
  2. 您实际上并没有存储水果的名称。你抓住它,但立即开始下一个循环而不存储它。
  3. 您没有跟踪每个结构。您需要为每个水果创建一个新结构。
  4. 确实要在值中保留双引号吗?

其他需要担心的事情:

  1. 你能保证属性列表是按这个顺序排列的吗?例如,Name 可以排在最后吗?

这是一些我认为你想要的代码。

#!/usr/bin/perl
use strict;
use warnings;
use Data::Dumper;
my %hash_table;
my $name;

my @fruit;

my $file = '/tmp/fruitdir/fruit1.txt';
open my $fh, "<", $file or die "Can't open $file: $!";
while (<$fh>) {
    chomp;

    # save hash table if there's a close bracket, but
    # only if it has been filled
    if ( /^\s*}\s*$/ ) {
        next unless keys %hash_table;

        # save COPY of hash table
        push @fruit, { %hash_table };

        # clear it out for the next iteration
        %hash_table = ();
    }

    # only parse lines that start with Name or fruit
    next unless
      my ( $key, $value ) =
      /^
         # skip any leading spaces
         \s*

         # parse a line beginning with Name or fruitXXXXX
         (
          Name
          |
          fruit[^\s]+
        )

        # need space between key and value
        \s+

        # everything that follows is a value. clean up
        # double quotes in post processing
        (.*)
     /x;

    # remove double quotes
    $value =~ s/"//g;

    if ( $key eq 'Name' ) {
        $name = $value;
    }
    else {
        $key = "${name}.${key}";
    }
   $hash_table{$key} = $value;
}

print Dumper \@fruit;

这是输出:

$VAR1 = [
          {
            'fruit 1.fruitValue' => '6',
            'fruit 1.fruitName' => 'apple.fru',
            'Name' => 'fruit 1',
            'fruit 1.fruitCount' => '5',
            'fruit 1.fruitId' => '0'
          },
          {
            'fruit 2.fruitName' => 'orange.fru',
            'fruit 2.fruitId' => '1',
            'fruit 2.fruitCount' => '10',
            'fruit 2.fruitValue' => '20',
            'Name' => 'fruit 2'
          }
        ];

【讨论】:

    猜你喜欢
    • 2016-02-21
    • 1970-01-01
    • 2012-07-22
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-10-27
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多