grepで行毎ではなく、空行を区切りとして検索結果を表示したい。

つまり、perlやawkで言うところのレコードセパレータを”¥n¥n”にして、検索結果を表示させたいということです。
現在はperlでこの処理をさせているが、遅いため、grepを直に使うことで高速化出来ないかと考えています。
grep -C オプションで、1レコード分以上の出力を抜き出しておいて、後から余計な部分を落とすとか考えましたが、簡潔な方法があれば教えてください。

回答の条件
  • URL必須
  • 1人2回まで
  • 登録:
  • 終了:--
※ 有料アンケート・ポイント付き質問機能は2023年2月28日に終了しました。

回答1件)

id:shampoohat No.1

回答回数347ベストアンサー獲得回数0

ポイント40pt

> 現在はperlでこの処理をさせているが、遅いため、


「遅いため」ですか。。。。


下記:


grep ***** input.txt | sed ”s/$/¥n/” > output.txt


でも、駄目でしょうか? これは、


grep ***** input.txt | perl -pe ”s/$/¥n/” > output.txt


と、等価なためナンセンスな回答である可能性はあると思いながらも、perl自体のプロセスの起動に時間がかかるなどして遅いのであれば、上記のsedへの置き換えで改善しますし。。。

id:stealthinu

これだと抜き出した後、空行を開ける、になりませんか?

今perlでやらせている内容は、レコードセパレータを”¥n¥n”にして読み込み、そのレコード中に合致するパターンがあれば、それを出力する、という感じです。

それとも、先にsedで空行区切りまでをまとめておいて、それを検索掛ける、というアイデアでしょうか。

ただ、ちょっといろいろとやってみて、速度的に満足行くところまで自己解決できましたので、これで終了にさせていただきます。

先にgrep -Cで1レコード分をだいたい抜き出しておいてから、perlで空行区切りで読み込んで抽出、という方法です。

---

#!/usr/bin/perl

$grep=”/usr/local/bin/grep”;

$record_max_lines=20;

$/=”¥n¥n”;

$target=shift;

open( GREP, ”$grep -C $record_max_lines $target |”);

while( <GREP> ) {

print if ( /$target/ );

}

2005/05/11 18:45:10
  • id:shampoohat
    申し訳ありません、誤読です。

    空行を区切りとして、表示をしたいのではなくて、検索をしたいのですね。

    駄目回答を入れてしまい、大変お恥ずかしい次第です。
    赤面しながら、ちょっとスクリプトを書いてみました。
    下記あたりじゃないでしょうか?

    perlを良く知らないので、駄目な部分があったらすみません。

    ------------------------------------------------------
    #!/usr/bin/perl

    $target=shift;

    $buf = ””;

    while( <STDIN> ) {
    $line = $_;
    $buf .= $line;
    if( $line =~ /^$/ ) {
    if( $buf =~ m/$target/ ) {
    print ”$buf”;
    }
    $buf = ””;
    }
    }
    if( $buf =~ m/$target/ ) {
    print ”$buf”;
    }
    ------------------------------------------------------
  • id:stealthinu
    Re:申し訳ありません、誤読です。

    >駄目回答を入れてしまい、大変お恥ずかしい次第です。
    いえいえ、お答えいただき、ありがとうございました。

    実はperlだと、すごく簡単に書けます。
    ---
    #!/usr/bin/perl
    $/=”¥n¥n”;
    $target=shift;
    while( <> ) {
    print if ( /$target/ );
    }
    --
    空行を区切り子として指定し、マッチするレコードがあったらそのまま表示、という内容になります。
    ただこれだと、サーバのログファイルなど、すごく大きなファイルについては検索にすごく時間がかかります。
    grepとは雲泥の差です。
    で、なにかうまいコマンドやgrepの使い方がないかな?と思ったのでした。

    ただ、前に自分の書いたコードでも、レコードの長さによっては2重に表示されたりする恐れがあるため、結局grepを修正して使おうと思っています。

この質問への反応(ブックマークコメント)

「あの人に答えてほしい」「この質問はあの人が答えられそう」というときに、回答リクエストを送ってみてましょう。

これ以上回答リクエストを送信することはできません。制限について

回答リクエストを送信したユーザーはいません