解析文本文件并在 perl 中创建复杂的树结构 [英] Parse Text file and create complex tree structure in perl

查看:35
本文介绍了解析文本文件并在 perl 中创建复杂的树结构的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个如下所示的输入文本文件:

I have an input text file which looks like this:

DEV=T124^BRD=100^IO=HDMI^MODE=1^REG=ABC^FLD=X^VAL=200
DEV=T124^BRD=100^IO=HDMI^MODE=1^REG=ABC^FLD=Y^VAL=100
DEV=T124^BRD=100^IO=HDMI^MODE=2^REG=ABC^FLD=X^VAL=100
DEV=T124^BRD=100^IO=HDMI^MODE=2^REG=ABC^FLD=Y^VAL=200
DEV=T124^BRD=100^IO=DP^MODE=1^REG=XYZ^FLD=X^VAL=200
DEV=T124^BRD=100^IO=DP^MODE=1^REG=XYZ^FLD=Y^VAL=100
DEV=T124^BRD=100^IO=DP^MODE=1^REG=MLK^FLD=X^VAL=200
DEV=T124^BRD=100^IO=DP^MODE=1^REG=MLK^FLD=Y^VAL=100

我想解析它并将其输出到一个看起来像这样的文件:

and I would like to parse it and output it to a file which looks like this:

DEV:T124
  BRD:100 
    IO:HDMI 
      MODE:1 
        REG:ABC 
          FLD:X,VAL:200                
          FLD:Y,VAL:100          
      MODE:2
        REG:ABC 
          FLD:X,VAL:100                
          FLD:Y,VAL:200          
    IO:DP 
      MODE:1 
        REG:XYZ 
          FLD:X,VAL:200                
          FLD:Y,VAL:100          
        REG:MLK 
          FLD:X,VAL:200                
          FLD:Y,VAL:100

我确实看过这个例子,但它并没有完全解决我的问题,因为 Data:Dumper 会将它打印成树状结构.Perl 中哈希数组树的路径列表

I did look at this example but it doesn't solve my problem completely as Data:Dumper will print it into a tree structure. List of paths into hash array tree in Perl

此外,我是 Perl 的新手,不了解散列的散列,尤其是在此评论中:https://stackoverflow.com/a/13209256/3430142

Also I am a novice in Perl and don't understand the hash of hashes especially in this comment: https://stackoverflow.com/a/13209256/3430142

我使用了该评论中发布的代码并编写了以下代码(@rows 是一个包含输入文件中行的数组).

I used the code posted in that comment and wrote the following(@rows is an array that contains the lines in the input file).

我不了解 foreach 循环的工作原理.因此,如果我将来需要更改它,我不知道该怎么做.这就是为什么我要求一个替代实现的原因,我可以自定义/理解而不是依赖该代码.

I don't follow how the foreach loop works. So in case I need to change it in future, I don't know how to do it. That is the reason why I was asking for an alternate implementation which I can customize/understand rather than relying on that code.

我使用了一些 Dumper 方法来编辑某些内容.我还使用 Tie 删除了大括号和引号.

I used few Dumper methods to edit certain things. I also used Tie to remove curly brackets and quotes.

open TREE, "+>", $ARGV[1] or die $!;
my $tree = {"" => {}};
foreach my $input (@rows) { 
    chomp $input;       
    my $t = $tree;
    $t = $t->{$_} //= {} for split /\^/ => $input;
}

$Data::Dumper::Indent = 1;
$Data::Dumper::Sortkeys = 1;
$Data::Dumper::Useqq = 1;
$Data::Dumper::Varname = "PROD";
$Data::Dumper::Terse = 1;
$Data::Dumper::Purity  = 1;
$Data::Dumper::Sparseseen = 1;
$Data::Dumper::Sortkeys = 1;
$Data::Dumper::Pair = "";
$Data::Dumper::Quotekeys = 1;

print TREE Dumper $tree;
close TREE;

tie @PST, 'Tie::File', $ARGV[1] or die $!;
for (@PST) {
    s/[\{\},"]//g;
}
untie @PST;

输出如下所示:

DEV:T124
  BRD:100 
    IO:HDMI 
      MODE:1 
        REG:ABC 
          FLD:X
            VAL:200   



          FLD:Y
            VAL:100     



      MODE:2
        REG:ABC 
          FLD:X
            VAL:100    



          FLD:Y
            VAL:200     




    IO:DP 
      MODE:1 
        REG:XYZ 
          FLD:X
            VAL:200                



          FLD:Y
            VAL:100          



        REG:MLK 
          FLD:X
            VAL:200            



          FLD:Y
            VAL:100

如您所见,我无法删除通过移除花括号创建的新行,而且我也无法获得我想要的结构,因为 Dumper 已经创建了一个预定义的树.

As you can see, I couldn't get rid of the new lines that were created by removing the curly braces, and I also can't get the structure I want as the Dumper already created a pre-define tree.

感谢您的帮助.

推荐答案

如果你可以接受排序的键,那么在你创建 $tree 之后的以下内容将根据方式做你想做的大部分事情你创建你的哈希:

If you can live with sorted keys, the following right after you create $tree will do mostly what you want based on the way you create your hash:

dump_tree($tree);

sub dump_tree {
    my ($hashR, $indent) = @_;

    $indent ||= 0;          # In case use warnings
    foreach my $key (sort keys %$hashR) {
        (my $print_key = $key) =~ s/=/:/;
        print TREE ((' ' x $indent), "$print_key\n");
        dump_tree($hashR->{$key}, $indent+2);
    }
}

它不会像您的示例那样将同一行上的 FLD:,VAL: 加倍.这应该是一个相对容易的补充,在递归到 dump_tree 之前,您可以检查是否只有一个更深的级别.

It doesn't double up the FLD:,VAL: on the same line, as your example did, though. That should be a relatively easy addition where you can check if you have only one more deeper level with a single key before you recurse into dump_tree.

这篇关于解析文本文件并在 perl 中创建复杂的树结构的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆