2012-11-13 46 views
3

匹配多線我與格式用perl -e

location: 
rome 

participants: 
cesar 
pompei 
Sylla 

一個文件,我試圖調用perl獲得值給出一個關鍵,例如我與參數participants函數將返回

cesar 
pompei 
Sylla 

我面臨的問題是,沒有選項-n似乎我的正則表達式沒有任何作品。 例如我期待

> perl -e '/(.*)/ms && print "$1\n" ' input.txt 

打印整個文檔。

回答

1

測試這alitle:

# cat file 
location: 
rome 

participants: 
cesar 
pompei 
Sylla 

現在得到participants

# perl -e 'undef $/; $_=<>; /participants:\s*(.*?)(\n\n|$)/s && print "$1\n";' file 
cesar 
pompei 
Sylla 

UPD:由於TLP提到的,它可以與-0開關改寫:

# perl -0777 -e '$_=<>; /participants:\s*(.*?)(\n\n|$)/s && print "$1\n";' file 
cesar 
pompei 
Sylla 
+1

'undef $ /'=='-0777'命令行開關。 – TLP

+0

好tnx會知道=) – PSIAlt

+0

非常感謝答案!我將修改尾部正則表達式組'(\ n \ n | $)',這是太嚴格了。 * ps:一旦你發佈,詳細闡述-0777 :),這就是我一直在尋找的*。 – UmNyobe

1

如果您不使用-n,則必須明確地讀取輸入,例如,

while(<>){do...} 

你沒有得到一個匹配,因爲你實際上沒有從stdin中讀取任何東西。

+0

是的,但我已經知道'while(<>)',我不想使用它。 – UmNyobe

2

通過默認-n-p將餵給您的單行腳本一個輸入ne一次。因此,要使用多行搜索,您必須告訴perl使用不同的記錄分隔符。使用-0選項。

要讀取一行整個文件:

perl -0777 -ne '...' input.txt 

要使用「段落模式」(分割在兩個或多個連續的換行符,這可能是你想要的這個問題):

perl -00 -ne '...' input.txt 
4

雖然在命令行中,你還不如用款方式:

perl -MData::Dumper -00 -anlwe 
    '$h=shift @F; $a{$h}=[@F]; }{ print Dumper \%a;' ceasar.txt 

輸出:

$VAR1 = { 
      'participants:' => [ 
           'cesar', 
           'pompei', 
           'Sylla' 
          ], 
      'location:' => [ 
          'rome' 
         ] 
     }; 

說明:

  • -MData::Dumper使用數據::翻車機模塊。這只是爲了演示,而不涉及你的問題。
  • -00使用段落模式,這意味着 - 簡單地說 - 將輸入記錄分隔符設置爲\n\n,以便輸入在雙換行符上分開。
  • -a將段落分割爲空格。您可以使用-F'\n'來限定它,以便僅在換行符上進行拆分。
  • -n隱含while (<>)環繞程序。
  • -l這個例子不是嚴格要求的,但它以一種方便的方式處理換行符的結尾。
  • @F是autosplit選項使用的數組。意思是我們把段落中的第一個單詞作爲首標,其餘的單詞作爲參數。
+0

不錯!與JSON :: XS相同'perl -MJSON :: XS -00 -anlwe'$ h = shift @F; $ A $ {H} = [@ F]; } {$ coder = JSON :: XS-> new-> ascii-> pretty-> allow_nonref; print $ coder-> encode(\%a);'' –

+0

非常感謝關於命令行開關的解釋!所以'a'是一個表的關聯數組?非常強大的... – UmNyobe

+0

@UmNyobe這是一個散列,頭部作爲鍵和數組的名稱作爲值。一旦你解析了輸入,你就可以輕鬆訪問任何一個頭文件。 – TLP