2012-09-26 51 views
1

我有以下格式的數據輸出。 我從控制檯上的命令獲取此輸出。Perl - 格式化輸出數據

Number: 9 
state: Online 
Data:    W1F-9YN 
Device: 41 
Number: 10 
state: Online 
Inquiry Data:    W1-9YN     
Device: 41 
Number: 11 
state: Online 
Inquiry Data:    W1-9YN     
Device: N/A 
Number: 42 
state: Online 
Data:  WD-W WDZ-04J     

但是,現在我想將其更改爲輸出表格格式。 就像如下圖所示

Device number state data 
41  10  online WY1-996 
42  12  offline WY2-996 
.   .  .  . 
.   .  .  . 
.   .  .  . 

我試着用如下的代碼做的,但我不能夠在正確的格式和一段時間在一個單一的列中的所有數據顯示,高達安排。任何人都可以幫我嗎?

open WDLIST, "Command"; 

while (<WDLIST>) { 

    if (m/Device\s*:\s*(\d+)/) { 

     $enDevice = $1; 
     print "$enDevice"; 
    } 

    if (m/Number\s*:\s*(\d+)/) { 

     $umber = $1; 
     print "$Number"; 
     chomp; 
    } 

    if (m/state\s*:\s*(w+)/) { 

     $State = $1; 
     print"$State"; 
    } 

    if (m/Data\s*:\s*(w+)(d+)(\-)(\s)/) { 

     $Data = $1; 
     print"$Data"; 
    } 
} 

謝謝!

+0

這很像http://stackoverflow.com/questions/12606045/converting-form-layout-to-table-csv-layout- in-perl – RobEarl

+0

這個問題似乎只對每個輸入文件有一行數據,對於簡單的數據CSV文件格式化起來要容易得多。 (直到你意識到你的數據可以包含逗號和引號) – pmakholm

+0

一些提示:1.你沒有正確匹配最後一行。確保你的正則表達式匹配你想要捕捉的東西。 2. $ umber - 是一個錯字嗎? 3.您不打印製表符,並且不打印換行符。 – Bitwise

回答

1

您可以使用printf格式化輸出。最簡單的解決辦法是用

printf "%-10s", $variable; 

這全部更換打印語句將打印變量留在10個字符寬列合理的。此外,您需要在每個數據塊的開始或結束處打印換行符。

更完整的解決方案,我會收集所有數據的哈希值的行,只要你檢測數據塊的末尾打印:

printf "%-10s %-10s %-10s %-10s\n", $info{device}, $info{number}, $info{state}, $info{data}; 

(或使用散列切片更簡潔代碼)

基於每個Device字段表示新設備的開始的假設。我會改變你的代碼來完成工作:

open WDLIST, "Command"; 

my %device; 

printf "%-10s %-10s %-10s %-10s\n", qw(Device number state data); 
while (<WDLIST>) { 
    if (m/Device\s*:\s*(\d+)/) { 

     # Print previous device, if any. 
     printf "%-10s %-10s %-10s %-10s\n", @data{ qw(id number state data) } 
      if exists $device{id}; 

     # Reset the current device and set the id 
     %device = (id => $1); 
    } 

    if (m/Number\s*:\s*(\d+)/) { 
     $device{number} = $1; 
    } 

    if (m/state\s*:\s*(w+)/) { 
     $device{state} = $1; 
    } 

    if (m/Data\s*:\s*(w+d+-\d+)/) { 
     $device{data} = $1; 
    } 
} 
# Print the last device (if any) 
printf "%-10s %-10s %-10s %-10s\n", @data{ qw(id number state data) } 
    if exists $device{id}; 

(我有點不確定什麼數據field最後的正則表達式真的應該是你的榜樣是不相符的,至少你會需要解釋。示例輸入的數據字段與示例輸出之間的關係)

+0

如果我在block的結尾處打印換行符,如果block或while block?如果我在每個if循環的末尾添加一個新行,它只是給出新行。你如何收集一行數據。你可能會看到前三名應該排在第一排,接下來的三排應該排在前面?對於爲什麼它是單列打印,我也很困惑。如果我給tab也不起作用。 – JumpOffBox

+0

在這兩種情況下都沒有提到數據塊。您需要一種方法來確定哪些字段屬於一起。根據你的例子,可能每個設備都以「Device:」字段開始。 – pmakholm

+0

謝謝麥。 但是你在哪裏打印這些數據。我嘗試了你發佈的想法,但它不打印任何東西。 – JumpOffBox