2016-04-14 51 views
1

所以,我有這個文件,它包含不同文件的不同路徑,以及文件類型隨着行數的變化而變化。像這樣的東西解析Perl中的文本文件並將信息存儲在JSON中

abc123: 
    Files Changed:        lines: new deleted unchanged 
    some/path/to/file.c        15  0   4234 
    some/other/file.h         1  0   223 
    some/other/path/to/file2       3  1    3 
    Files Created:        lines: new deleted unchanged 
    some/path/to/file.c        3  1    3   
    Files Changed:        lines: new deleted unchanged 
    some/other/path/to/file       2  2   234 

我需要找到一個簡單的方法來解析這個。我真的不在乎線路的變化(新的,刪除的,不變的)。我想要的是有一個JSON。事情是這樣的:

{ 
    "abc123":{ 
     "Files Changed:": [ 
      "some/path/to/file.c", 
      "some/other/file.h", 
      "some/other/path/to/file", 
      "some/other/path/to/file2" 
     ], 
     "Files Created:":[ 
      "some/path/to/file.c" 
     ] 
    } 
} 

比較困難的部分是試圖分析文本文件我想要的東西,可以用什麼文件給你工作。我所知道的肯定可能會有效的是任何具有'/'的文件都是一個文件字符串,但我不知道如何告訴它它是'File Changed'還是'File Created'。此外,該文件可能具有像'文件已刪除''文件鏈接'與其相應的文件路徑。如何實現這一點的任何幫助將不勝感激。

+0

如果行開頭的空格是一致的,這很容易實現。你只需要逐行閱讀,並記住你在最後一個級別上看到了什麼。這是git輸出嗎? – simbabque

回答

3

只要行首的空白符合,就很容易實現。您需要逐行閱讀,並記住您在哪個級別上看到的內容。

在下面的代碼中,我假設每個級別有兩個縮進空格。因爲這看起來像是某種版本控制的總結,我打電話

  • 壓痕的第0級ABC123$commit
  • 和1級已經做了下面列出的文件$operation
  • 第二級包含文件名。
use strict; 
use warnings; 
use JSON 'to_json'; 

my $commit; # abc123 
my $operation; # Files Changed, Files Created 
my $data; # this is the target 

while (my $line = <DATA>) { 
    if ($line =~ /^(\S+):/) { 
     # line contains a commit 
     $commit = $1; 
     next; 
    } 
    if ($line =~ /^\s\s([^:]+):/) { 
     # line contains an operation 
     $operation = $1; 
     next; 
    } 
    if ($line =~ /^\s\s\s\s(\S+)/) { 
     # this is a filename 
     push @{ $data->{$commit}->{$operation} }, $1; 
    } 
} 

print to_json $data; 

__DATA__ 
abc123: 
    Files Changed:        lines: new deleted unchanged 
    some/path/to/file.c        15  0   4234 
    some/other/file.h         1  0   223 
    some/other/path/to/file2       3  1    3 
    Files Created:        lines: new deleted unchanged 
    some/path/to/file.c        3  1    3 
    Files Changed:        lines: new deleted unchanged 
    some/other/path/to/file       2  2   234 

這將產生以下輸出。

{"abc123":{"Files Changed":["some/path/to/file.c","some/other/file.h","some/other/path/to/file2","some/other/path/to/file"],"Files Created":["some/path/to/file.c"]}} 
+0

你是一個救世主!沒有想到空間。有效!謝謝! –