2012-10-09 84 views
3

文件中讀取多行值有一個屬性文件,說我如何從使用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 - 每個與我可以分割基於所述定界符,:

對於給定屬性(比如Property1)和給定列(一串相關聯說a1)我需要返回第二列(這裏b1

的代碼應該可以忽略註釋,空格等

謝謝提前

回答

0

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

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; 
} 

任何時間\行的目的,以下換行符被刪除。這將把每個多行屬性放在一行上。

缺點是這會將整個文件讀入內存;如果您的輸入文件非常大,您可以將其適應於逐行掃描文件的算法。

+1

是否有downvoting這個答案什麼特別的原因? – dan1111

+0

不,只是upvoted you – snoofkin

5

大多數文本處理 - 包括處理反斜槓延續線 - 在Perl中非常簡單。所有你需要的是一個像這樣的讀取循環。

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

下面的程序做我認爲你想要的。我在讀循環中放入了一個print調用,以顯示已經通過連續行聚合的完整記錄。我還演示瞭解壓縮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 }, 
} 
+0

嗨..感謝您的幫助...但還有一個問題,我想不出來.. 在上面的例子中...對於從最後的第4行,如果我說 $ propName =「Property1」; print $ data {$ propName} {a1},「\ n \ n」; 它工作正常.... 但有一些變數說$ propName在適當的時候發生了變化.. print $ data {$ propName} {a1},「\ n \ n」; 它不打印任何... 我試圖在此打印語句之前打印$ propName名稱...它打印那裏..但此打印語句不打印任何... 這樣的事情 print $ propName print $ data {$ propName} {a1},「\ n \ n」; 請幫我 –

+0

請忽略以上評論.. 使用chomp()函數解決了這個問題.. –