簡體   English   中英

如何使用Perl從文件中讀取多行值

[英]How to read multi-line values from a file using Perl

我有一個屬性文件,比方說

##
## Start of property1
##
##
Property1=\
a:b,\
a1:b1,\
a2,b2
##
## Start of propert2
##
Property2=\
c:d,\
c1:d1,\
c2,d2

請注意,任何給定屬性的值可以分為多行。

我想用Perl讀取這個屬性文件。 這在Java中運行良好,因為Java使用反斜杠支持多行值,但在Perl中它是一個噩夢。

在上面的屬性文件中有兩個屬性 - Property1Property2 - 每個Property2都與一個字符串相關聯,我可以根據分隔符進行拆分,並且:

對於給定的屬性(比如Property1 )和給定的列(比如a1 ),我需要返回第二列(這里是b1

代碼應該能夠忽略注釋,空格等。

提前致謝

在Perl中,大多數文本處理(包括處理反斜杠延續行)都非常簡單。 你只需要一個像這樣的讀取循環。

while (<>) {
  $_ .= <> while s/\\\n// and not eof;
}

下面的程序做我認為你想要的。 我在read循環中放置了一個print調用,以顯示已經在continuation行上聚合的完整記錄。 我還演示了提取你給出的b1字段作為示例,並顯示了Data::Dump的輸出,以便您可以看到創建的數據結構。

use strict;
use warnings;

my %data;

while (<DATA>) {
  next if /^#/;
  $_ .= <DATA> while s/\\\n// and not eof;
  print;
  chomp;
  my ($key, $values) = split /=/;
  my @values = map [ split /:/ ], split /,/, $values;
  $data{$key} = \@values;
}

print $data{Property1}[1][1], "\n\n";

use Data::Dump;
dd \%data;


__DATA__
##
## Start of property1
##
##
Property1=\
a:b,\
a1:b1,\
a2,b2
##
## Start of propert2
##
Property2=\
c:d,\
c1:d1,\
c2,d2

產量

Property1=a:b,a1:b1,a2,b2
Property2=c:d,c1:d1,c2,d2
b1

{
  Property1 => [["a", "b"], ["a1", "b1"], ["a2"], ["b2"]],
  Property2 => [["c", "d"], ["c1", "d1"], ["c2"], ["d2"]],
}

更新

我再次閱讀了您的問題,我認為您可能更喜歡不同的數據表示形式。 此變體將proerty值保留為哈希值而不是數組數組,否則其行為是相同的

use strict;
use warnings;

my %data;

while (<DATA>) {
  next if /^#/;
  $_ .= <DATA> while s/\\\n// and not eof;
  print;
  chomp;
  my ($key, $values) = split /=/;
  my %values = map { my @kv = split /:/; @kv[0,1] } split /,/, $values;
  $data{$key} = \%values;
}

print $data{Property1}{a1}, "\n\n";

use Data::Dump;
dd \%data;

產量

Property1=a:b,a1:b1,a2,b2
Property2=c:d,c1:d1,c2,d2
b1

{
  Property1 => { a => "b", a1 => "b1", a2 => undef, b2 => undef },
  Property2 => { c => "d", c1 => "d1", c2 => undef, d2 => undef },
}

假設您的文件不是太大,這是一個簡單的方法:

use strict;
use warnings;

open FILE, "my_file.txt" or die "Can't open file!";

{
    local $/;
    my $file = <FILE>;
    #If \ is found at the end of the line, delete the following line break.
    $file =~ s/\\\n//gs;
}

每當一行以\\結尾時,將刪除以下換行符。 這會將每個多行屬性放在一行上。

缺點是這會將整個文件讀入內存; 如果您的輸入文件非常大,您可以將其調整為逐行遍歷文件的算法。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM