複数の一致に対して一致するファイル名を一度だけ印刷する方法(ファイル名のみを印刷するのではありません)

複数の一致に対して一致するファイル名を一度だけ印刷する方法(ファイル名のみを印刷するのではありません)

同時に、複数のログの内容をスクラップしています。grep -Er

しかし、ファイルプレフィックスを一度だけ一致させたいと思います。

私が達成しようとしているものは次のとおりですls -lr(ファイルを一度一致させ、そのファイルごとに一致するすべての行)

ドキュメントでこのオプションが見つかりませんでした。

grepだけでできますか?どのように?

ベストアンサー1

grep私が知っている限り、実装はありません。-r標準オプション自体ではありません。findファイルを見つけて一致perlさせ、ファイルパスを報告する関数をスクリプトまたは関数に簡単に実装できます。

rPgrep() {
  local pattern="$1"
  shift
  find -- "$@" -type f -print0 |
    perl -C -0se '
      @ARGV = <STDIN>;
      $ /= "\n";
      while (<<>>) {
        if (/$pattern/) {
          unless ($header_already_printed) {
            print "\n" if defined $header_already_printed;
            print "$ARGV:\n";
            $header_already_printed = 1;
          }
          print;
        }
        $header_already_printed &&= 0 if eof;
      }' -- -pattern="$pattern"
}

それから:

rPgrep pattern some/dir some/other/dir or/regular/file

一般ファイルへのシンボリックリンクも表示するには(GNU仮定)-typeに置き換えます。または、GNU(代わりに)などのディレクトリツリーを下げるときにシンボリックリンクをたどるオプションを追加します。-xtypefind-Lfindgrep -R-r

ボーナスに限定された正規表現の代わりに、Perl正規表現(grepサポートされているいくつかの正規表現に似ています)を取得できます。-P延長するあなたが得るもの-E

大文字と小文字を区別しない一致(-i)または言葉マッチング(-w)、リバースマッチング( ) 、-vまたは行全体のマッチング(-x)は正規表現構文((?i)、、、、、)を使用して実行できますが、他のオプション(、または// /などのいくつかの非標準拡張)の場合... Perlコードを修正する必要があります。\b(?!...)^...\zgrep-n-l-F-o-A-B-C

次のこともできます。

find . -type f -exec grep -q pattern {} ';' \
               -exec printf '\n%s:\n' {} ';' \
               -exec grep pattern {} ';'

ただし、これはファイルごとに最大3つのコマンドを実行することを意味するため、非常に非効率的です。

GNUの場合、findこれ-exec printf '\n%s:\n' {} ';'に置き換えることができます-printf '\n%p:\n'

おすすめ記事