2012-04-21 3 views
1

私はこのようにフォーマットされているHTMLファイルのシリーズを持っている:マルチレベルのgrep

映画館の名前が一番上に一つだけを、リストされている
cinema name 
film 1 
    showtime 1 
    showtime 2 
    ... 

film 2 
    showtime 1 
    showtime 2 
    showtime 3 
    ... 

。映画のリストがあります(ここでは1からnまでの数の映画があります)。その後、上映時間のリストも表示されます(もう一度、1日中に1つ以上になることがあります)。

私は抽出したいgrepの出力に何かを使用して、この情報は次のように:しかし

cinema name - film 1 - showtime 1 
cinema name - film 1 - showtime 2 
cinema name - film 2 - showtime 1 
cineme name - film 2 - showtime 2 
cinema name - film 2 - showtime 3 
etc. 

、私はgrepをしてこれを実現する方法を/かどうかわからないんだけど、それが可能であるかのように、どのように

答えて

0

単一の発現ISN。??可能ですが、あなたは5でそれをすることができます:

空白行を削除します(いくつかのstu FF): 検索: "\ n個の\ n" は 置き換え: "\ n" は

は、フィルムをダウンフィル:

は(映画の後、以前の上映時間の任意の数で始まるショータイムを検索します。膜が捕捉した後、ショータイムの先頭に付加される)

Find: "(?<=\n ([^ \n].+)(\n .*)*)\n " 
Replace: "\n $1 - " 

映画をダウン入力します。

は、(映画の後に以前の上映時間またはフィルムの任意の数で始まるショータイムを検索シネマ。捕獲され、その後、ショータイムの先頭に追加された)

Find: "(?<=(?:^|\n)([^ \n].+)(\n {1,2}.*)*)\n " 
Replace: "\n $1 - " 

が非ショータイムライン取り外します。

Find: "(?<=^|\n)(?! ).*\n" 
Replace: "" 
を回の

トリム上映時間:

Find: "\n " 
Replace: "\n" 

このすべてがテストされていないと\n行末で、.NETのような正規表現の構文を前提としています。味を調整する。

1

1つの正規表現ですべての問題を解決する必要はありません。この場合、私は先行する空白でどのような行を持っているか把握し、映画や映画の価値が何であるかを覚えておき、ショータイムに遭遇したときにそれらをまとめて印刷します。

perl -lne '(/\A\S/ and $c=$_) || (/\A\s(\S.*)/ and $f=$1) || (/\A\s\s(\S.*)/ and print"$c - $f - $1")' movies.txt 

#!perl 
use v5.10; 

my($cinema, $film); 
while(<DATA>) { 
    chomp; 
    if(/\A\S/)   { $cinema = $_ } 
    elsif(/\A\s(\S.*)/) { $film = $1 } 
    elsif(/\A\s\s(\S.*)/) { say "$cinema - $film - $1" } 
    } 


__END__ 
Regal 9 
Jaws 
    15:00 
    19:00 
    21:00 

Star Wars 
    16:00 
    17:00 
    18:00 

AMC 18 
E.T. 
    12:00 
    14:00 

Black Sheep 
    22:00 
    01:00 
    03:00 

ここではその醜いPerlのワンライナーのバージョンがあります:このソリューションはPerlでですが、あなたが選択した任意の言語で同じことを行うことができます