• ベストアンサー

Perlで特定行から特定行までを抜き出したい

皆さんのお知恵をお貸し頂ければ幸いです。 Perlで以下のようなことをしたいと考えています。 例えば、次のようなテキストファイルがあったとします。 example.log ================================== aaaa hogehoge test okok perl script ================================== 上記ファイルを読み込んで、「hogehoge」から「perl」の間に挟まれた行だけ抜き出したいのです。 イメージとしては、読み込んだファイルを配列に入れて、一行づつ読ませ、キーワード「hogehoge」が現れたらそこでフラグを立て、それ以降の行を表示し、キーワード「perl」が現れた時点で表示を止めるという処理になるのかな?と思っています。 このような場合、どういう風にすればいいのでしょうか? 恐れ入りますが、ご教授頂ければ幸いです。 それでは、どうぞよろしくお願い致します。

質問者が選んだベストアンサー

  • ベストアンサー
  • leaz024
  • ベストアンサー率75% (398/526)
回答No.3

> 一行づつ読ませ、キーワード「hogehoge」が現れたらそこでフラグを立て、それ以降の行を表示し、キーワード「perl」が現れた時点で表示を止めるという処理になるのかな?と思っています。 それでいいと思いますよ?これをそのままコード化すると、こんな感じでしょうか。(No.1さんのとはちょっと結果が違います。) open FH, "example.log" or die $!; $flag = 0; while ($data = <FH>) {   chomp $data;   if  ($data eq "hogehoge") { $flag = 1 }   elsif ($data eq "perl")    { $flag = 0 }   elsif ($flag) { print "$data\n" } } close FH; で、もっと略したいPerlな人だとこんな感じ。Perl独特の記法がふんだんに使われているので、勉強するには不向きかもしれませんが^^; open FH, "example.log" or die $!; while (<FH>) {   print if /^hogehoge$/ .. /^perl$/ and !/^(?:hogehoge|perl)$/; } close FH; ※インデントに全角空白を使っているので、コピーする場合はタブなどに置換して下さい。

edaeda8765
質問者

お礼

こちらもありがとうございます。 両方の方法で目的通りの動きをすることが確認出来ました。 ただ、後の方の構文はNo2さんが教えて下さったのと同様に、勉強不足の為なぜ動くのかがわかっていない次第です^^;

全文を見る
すると、全ての回答が全文表示されます。

その他の回答 (2)

  • t140
  • ベストアンサー率39% (59/150)
回答No.2

#Perlな人は .. 演算子を使ってこう書くかも知れません while (<IN>){ if ($_ eq "hogehoge\n" .. $_ eq "perl\n"){ print; } } #目的の位置まで読み飛ばして、目的の最後のキーワードが #見つかり次第ループを抜けるならこう書くこともできます 1 while <IN> eq "hogehoge\n"; while(<IN>){ print; $_ eq "perl\n" and last; } #もっとデータが大量にある場合に高速で抜き出すには #read関数を使って書くこともできますが、複雑なので #割愛します。

edaeda8765
質問者

お礼

お世話になります。 こちらの内容でもいけるようです。 ただ、構文が理解出来ていない為、なぜ動くのがわからないのが難点です^^;; ともあれ、ありがとうございました。

全文を見る
すると、全ての回答が全文表示されます。
  • helonpa
  • ベストアンサー率38% (108/278)
回答No.1

Perlな人はもっと略したいでしょうけど素直に書けば。 $flag=0; open(FH, "< ./example.log"); while($data = <FH>){   print "$data\n" if $flag==1;   chomp $data;   $flag=1 if $data eq "hogehoge";   $flag=0 if $data eq "perl"; } close FH;

参考URL:
http://www.rfs.jp/sitebuilder/perl/
edaeda8765
質問者

お礼

ありがとうございました。 ご教授頂いた内容を少し弄りましたが、目的を達することが出来ました。

全文を見る
すると、全ての回答が全文表示されます。

関連するQ&A

  • perlで特定行から特定行までを抜き出しor置換

    perlで以下のようなことをしたいと考えています。 以下のことを、コマンドラインから「perl ~」という形で 実行したいのですが、どのよにすればよいでしょうか。 1.特定行から特定行までを抜き出し 2.特定行から特定行の範囲で文字列置換 例えば、次のようなテキストファイルがあったとします。 example.txt ================================== #START aaaa hogehoge test okok perl script #END ================================== 上記ファイルを読み込んで、 1.「#START」から「#END」の間に挟まれた行だけ抜き出し 2.「#START」から「#END」の間で、「test」を置換 のです。 sedで言うところの sed -e '/#START/,/#END/ s/YYYYMM/201603/g' test.txt をやりたいのです。

    • ベストアンサー
    • Perl
  • 外部ファイルを1行ずつ読み込んで特定カラムを引数として

    外部ファイルを1行ずつ読み込んで特定カラムを引数として 外部ファイルを1行ずつ読み込んで特定カラムを引数として 別び外部ファイルに対してgrepをかけたいと考えてます。 DBを作るほどのデータではないので、ファイルの行数を取得してawk/sedコマンド もしくはperlを駆使して実装できればと考えてます。スマートな方法があれば教授ねがいます。 やりたいこと)sample1.logから1/2カラム目を取得して、 sample2.logに対してsample1.logの2カラム目で紐付けて repot.logを出力したい #sample1.log 0001 AAAA 0002 BBBB 0003 AAAA 0004 CCCC  ・  ・ #sample2.log AAAA ABC BBBB DEF CCCC GHI  ・  ・  ・ #report.log 0001 AAAA ABC 0002 BBBB DEF 0003 AAAA ABC 0004 CCCC GHI  ・  ・  ・ 以上

    • ベストアンサー
    • Perl
  • 外部ファイルを1行ずつ読み込んで特定カラムを引数として

    外部ファイルを1行ずつ読み込んで特定カラムを引数として 別び外部ファイルに対してgrepをかけたいと考えてます。 DBを作るほどのデータではないので、ファイルの行数を取得してawk/sedコマンド もしくはperlを駆使して実装できればと考えてます。スマートな方法があれば教授ねがいます。 やりたいこと)sample1.logから1/2カラム目を取得して、 sample2.logに対してsample1.logの2カラム目で紐付けて repot.logを出力したい #sample1.log 0001 AAAA 0002 BBBB 0003 AAAA 0004 CCCC  ・  ・ #sample2.log AAAA ABC BBBB DEF CCCC GHI  ・  ・  ・ #report.log 0001 AAAA ABC 0002 BBBB DEF 0003 AAAA ABC 0004 CCCC GHI  ・  ・  ・ 以上

  • シェルスクリプト+perl

    シェルスクリプト中で1行だけperlを利用したいと思っています。 しかしシェルスクリプトで利用している変数をperlに持っていく方法が分からず悩んでいます。 ---------------------- #!/ban/bash hoge="hogehoge" perl -e ・・・ ←この中で$hogeを利用したい ---------------------- perlですべて書き直せばできるのですが、1行のためだけに、すべてを修正するのもどうかと思いましたので質問させていただきました。 もしご存知の方いらっしゃいましたらお教えください。

  • htm.ファイルから冒頭の一行だけを読み込むには

    Perl 初心者です。 過去ログのNo.285625 にもありましたが、ファイルの内容を一括して配列@xxに読み込んでprint "$xx[0]\n" とやっても一行目が表示されません。読み込みたいファイルはhtmファイルで一行目には<BR>で改行が入っているのですが、この一行が読めません。どうしたらよろしいのでしょうか?初歩的な質問で済みませんが、お願いします。

    • ベストアンサー
    • Perl
  • Perlでのselfの書き方

    お世話になっています。 今他人が作ったPerlのプログラムを見ているのですが、 その中で、 パラメータを受け取る部分が、、、 sub hogehoge { my $self = shift; my ($one, $two) = @_; .. bra bra bra } と言う感じになっています。 またPerl初心者ですが、私の調べたところでは、 この二つの行は同等の意味なので、 sub hogehoge { my ($self, $one, $two) = @_; ... bra bra bra } と一行でかけてしまうと思うのですが、 $selfと$one, $twoを2行に分けている理由とか あるのでしょうか。 $selfだけ2行目の方法ではかけないとか? それともただ単に、 my $self = shift; と1行目に書くのがならわしだからでしょうか。 詳しい方が居ましたらよろしくお願いします。

    • ベストアンサー
    • Perl
  • 変数名の動的な付け方?

    久しぶりにPerl/CGIを使って 今、少し変わったプログラムをPerl/CGIで作成しています。 そこで、悩みの種がでてきたのでご相談させていただきます。 例 log.cgi ------------------------------------ id<>hogehoge<> pass<>hogehoge<> time<>09/01/01<> ipad<>127.0.0.1<> ... というログファイルがあるとします。 何行あるかは状況によって変わりますので指定できません。 ただ、それはforeach等で対応できるかな?と思いました。 ここで私のやりたいことなんですが。 test.cgiというメインプログラムで上記ログを開いてから 前の項「id<>hogehoge<>」で言う「id」の部分をそのまま変数名にしてやりたいのです。 ログファイルを読み込む → 一行目を読み込み $id = "hogehoge"; とする → 二行目を読み込み $pass = "hogehoge"; とする ... foreachで対応できるかなーと山勘を探って見たのですが 動的に変数を定義するようなことってできるのでしょうか? お答え頂ければ幸いです。

    • ベストアンサー
    • CGI
  • Perl:大容量ログを正常に読み込む方法が知りたい

    ある動作のログを出力するシステムの機能改修の立場にある者です。 言語はperlです。 大容量ログを正常に読み込む方法が知りたいのですが、急いでおります。 ログが出力されているファイルが大容量で、 ログ読み込みの始めのうちは問題なく扱えていますが、 ログをどんどん読み込んでいくと 「Internal Server Error」となります。 スクリプトは下記の通りです。 open LOGFILE,○○ while($** = <LOGFILE>){ ログの文字列をいろいろ切り出して、配列に格納。 必要なログ情報を取り出せたらループから出る。 } close(LOGFILE); 上記の配列を扱い、ログを多様な表示スタイルで出力します。 ブラウザでのログ表示で検索条件で指定されたログを抽出できたら 途中でループから逃げているので問題なく動作しております。 しかし、ページを切り替え、ログをどんどん読み込んでいくと (おそらく)配列に格納するメモリが大容量のため エラーになってしまいます。 ※ログ表示で設置している検索条件機能 (1)何ページ目表示指定 (2)1ページあたりのログ表示行数指定 (100行表示で3ページ目を見る場合、201行目から300行が表示されます。) そのためページ切り替え毎にログを格納している配列を破棄?するなど メモリを解放することが必要になる?かと思っています。 しかし、ページ切り替えごとにログの一番初めから読み込み直す必要もあるのでは?とも考えています。 ※ログの一文目からカウンタで順番を数えていて、後でログを格納した配列でキーを指定してログを取り出しています。 検索条件を変えながらでも、かつメモリを解放?しながらログを配列に格納して扱う方法はあるでしょうか。 つまづいてしまって進めません。。 ※メモリを増やすといったパワープレーではなく、 プログラムの書き方でメモリの負荷を少なくして実現させたいです。 もしいい方法をご存知の方がいらっしゃれば、よろしくお願いいたします。 長文失礼いたしました。

  • 1行だけ削除。

    log.logというログファイルの中のデータから、 NAME=hoge&GROUP=hogehoge というような1行だけを削除する場合はどのようにしたらいいのでしょうか?

    • 締切済み
    • CGI
  • perl 複数ファイルから一行ずつ読み込んで比較

    初心者向けのperl参考書がなんとか理解できる程度のperl初心者です。 一週間ほど思考錯誤してきたのですが、いくらスクリプトを書いてもどうしても自分では解決できない処理がありましたので、初めてなのですが、質問させていただきました。 二つの同じ形式の、一部情報だけ異なるファイルから一行ずつ配列を読み込んで、数値の大小を比較したいのですが・・・ ファイル構造は、下のように2行でひとつのtextデータの情報を表示する形式となってまして、 奇数行には、各textファイルの情報が、.以下の部分に4552221.2:(30.2):100、のように記載されています。 偶数行には、各テキストファイルの、IDとなる情報が、13333331のように記載されています。この奇数行と、偶数行一行ずつで、ひとつのtextデータの 情報を表しています。textというファイルは、text1から順に,text2000000まで、 2000万程度,行で言えば4000万行ほど存在しています。よって、file1もfile2も、同じ行であれば、同じtextで、同じIDのものを示しています。ずれはありません。 file1 ----------------------------- >text1. 4552221.2:(30.2):100 13333331 >text2 87999999 >text3. 3444444.1:(20.0):300 75533333 ----------------------------- 数値は意味が変わらない範囲で、比較しやすい数値に変えてあります。 この上のfile1と、下のfile2を比べたいのですが、 file2 ----------------------------- >text1. 4552221.2:(20.9):100 13333331 >text2 87999999 >text3. 3444444.1:(23.3):300 75533333 ----------------------------- 偶数行のtextファイルの欄が大事で、text名のドット(.)の後に、続けて数値が書いてある場合(上ではtext1とtext3が該当)、そのドットの後の括弧()で囲まれた中の数値の大小を比較して、 差が一定以上あるtextだけを出力するスクリプトが書きたいと思っているのですが、 これをいきなりすべてひとつのスクリプトにまとめるのは、私の知識と力量では到底無理なので、ひとつひとつ段階を踏んで処理していこうと考えました。 1、奇数行の、text.の後半に情報があるもの場合、tempファイルにその奇数行と、対になる偶数行を出力する。それを、file1、file2、個別に行う。(temp1、temp2を出力) file1で取り除かれる3、4行目のtext2は、file2でも必ず取り除かれるので、1の処理後も、file1と2の各行は、比較することが可能な状態です。 2、正規表現を使って、各行の()で囲まれた部分の最初の2桁の数字(一部は一桁の数字の場合もあり)、をtempに出力する。(temp3、temp4を出力) (この処理を行わなくても可能かもしれませんが、ややこしいので、数字だけ出すようにしました) 最後に、file1とfile2の各行の数字を一行ずつ読み込んで、数値に一定以上の差がある行の情報だけ出力したいのですが、各行を順番に分析できる方法は、while文か、配列に読み込む方法しか知りません。 前者のwhile文では、ファイルオープンは、ひたつ以上は同時には取り扱えないという情報を得たので、使えない思っています。後者の配列に読み込む方法は、桁が大きいので、実用的ではないと感じています。 二つ以上のファイルの各行の特定の数値データを、一行ずつ順に比較して、差があるものだけ抽出するにはどのようなスクリプトを書けばよいのか、ご教授下さい。 いろいろ調べましたが、(僕の調べ方が悪いと思いますが)適切なコマンドや方法にたどり着けません。 試してみた方法 ファイルハンドルを二つ指定して、while文の条件中に、andで条件を二つ指定してファイルハンドルから読み込んでやればよいと思ったのですが、実行するとエラーになってしまいます。ググっていろいろ調べてみたところ、ファイルハンドルの二つ指定はできないとの記述を見つけたので、whileの条件に複数のファイルハンドルを記述するこの方法はあきらめて、ここで、ストップしています。 まわりに、perlを扱える方がいらっしゃれば質問に伺うのですが。もしよろしければ、簡単でもご教授いただけますと幸いです。宜しくお願い申し上げます。

    • ベストアンサー
    • Perl
このQ&Aのポイント
  • 仕事で動いているから運動しなくても良いという意見がある
  • 姉は仕事で動いているため、運動は必要ないと主張している
  • しかし、仕事してて皆太ってないなら世の中の人のほとんどはスリムなはずではないかという疑問がある
回答を見る

専門家に質問してみよう