暗黙的な AND パターン間、つまりシーケンスで複数のgrepsを実行するのと同じです:

grep pattern1 | grep pattern2 | ... 

では、どのように変換するのですか?

grep pattern1 & pattern2 & pattern3 

引数を動的に構築しているため、単一のgrepを使用したいので、すべてを1つの文字列に収める必要があります。フィルタの使用はシステム機能であり、grepではないため、引数ではありません。


この質問を次のように混同しないでください:

grep "pattern1\|pattern2\|..." 

これはまたはマルチパターンマッチです。

コメント

複数の検索パターンにgrepを使用するを参照

回答

agrepは、次の構文で実行できます:

agrep "pattern1;pattern2" 

GNU grepを使用して、ビルドされた場合w PCREサポートでは、次のことができます。

grep -P "^(?=.*pattern1)(?=.*pattern2)" 

grep

grep -X ".*pattern1.*&.*pattern2.*" 

.*をは、<x><y> 正確に、は、ab emの両方に できるような文字列がないため一致しません。 div>同時に)。

パターンが重ならない場合は、次のこともできる場合があります。

grep -e "pattern1.*pattern2" -e "pattern2.*pattern1" 

ポータブルな最良の方法は、おそらくすでに述べたようにawkを使用することです。

awk "/pattern1/ && /pattern2/" 

sed -e "/pattern1/!d" -e "/pattern2/!d" 

これらはすべて異なる正規表現構文を持つことに注意してください。

コメント

  • agrep構文が機能しない私…どのバージョンで導入されましたか?
  • @Raman 1992年の2.04 にはすでに含まれています。 ‘最初から’なかったと信じる理由はありません。 agrepの新しい(1992年以降)バージョンは、 glimpse / webglimpse に含まれています。おそらくあなたは別の実装を持っています。 ast-grepバージョンを間違えましたが、拡張正規表現のオプションは-Xであり-A
  • @St é phaneChazelasありがとうございます。Fedora23にagrep 0.8.0があります。参照しているものとは異なるagrepである。
  • @Raman、あなたは TRE

  • @Techiee、または単にawk '/p1/ && /p2/ {n++}; END {print 0+n}'
  • 回答

    grepバージョンを指定しなかったため、これは重要です。一部の正規表現エンジンでは、「& “ですが、これは非標準で移植性のない機能です。ただし、少なくともGNUgrepはこれをサポートしていません。

    OTOHgrepをsed、awk、perlなどに置き換えるだけです。 。(重量の増加順にリストされています)。 awkを使用すると、コマンドは

     awk "/regexp1/ && /regexp2/ && /regexp3/ { print; }" 

    のようになり、コマンドラインで簡単に指定できるように作成できます。

    コメント

    • awkはERE ‘を使用することを覚えておいてください。プレーンなgrepが使用するBRE ‘とは対照的に、grep -Eと同等です。
    • awk ‘の正規表現は呼ばれる EREですが、実際には’少し特異です。 wiki.alpinelinux.org/wiki/Regex
    • ありがとう、grep 2.7.3( openSUSE)。私はあなたに賛成しましたが、しばらくの間質問を開いたままにします。おそらくgrepにいくつかのトリックがあるかもしれません(awkが嫌いなわけではありません。 >
    • デフォルトのアクションは、一致する行を印刷することです。そのため、{ print; }の部分は’ここでは本当に必要または有用ではありません。

    回答

    patternsに1行に1つのパターンが含まれている場合、次のようなことができます:

     awk "NR==FNR{a[$0];next}{for(i in a)if($0!~i)next}1" patterns -  

    または、これは正規表現ではなく部分文字列に一致します式:

     awk "NR==FNR{a[$0];next}{for(i in a)if(!index($0,i))next}1" patterns -  

    入力の行がない代わりにすべてを出力するpatternsが空の場合は、NR==FNRFILENAME==ARGV[1]またはivid =に置き換えます。 gawkの “ce466acd98”>

    これらの関数は、引数として指定された各文字列を部分文字列として含むSTDINの行を出力します。 gaはgrepallを表し、gaiは大文字と小文字を区別しません。

     ga(){ awk "FILENAME==ARGV[1]{a[$0];next}{for(i in a)if(!index($0,i))next}1" <(printf %s\\n "$@") -; } gai(){ awk "FILENAME==ARGV[1]{a[tolower($0)];next}{for(i in a)if(!index(tolower($0),i))next}1" <(printf %s\\n "$@") -; }  

    コメント

    • いくつかの使用例と動作に対応する明確な回答(macosで確認済み)

    回答

    grep pattern1 | grep pattern2 | ...

    引数を動的に構築しているため、単一のgrepを使用したいので、すべてを1つの文字列に収める必要があります

    パイプラインを動的に構築することは実際に可能です(evalに頼ることなく):

     # Executes: grep "$1" | grep "$2" | grep "$3" | ... function chained-grep { local pattern="$1" if [[ -z "$pattern" ]]; then cat return fi shift grep -- "$pattern" | chained-grep "$@" } cat something | chained-grep all patterns must match order but matter dont  

    ただし、おそらくあまり効率的なソリューションではありません。

    コメント

    • chained-grep()またはfunction chained-grepを使用しますが、function chained-grep()は使用しません:unix.stackexchange.com/questions/73750/ …
    • トリックとは何か説明していただけますか?回答に追加できますか( なし “編集:”、 “更新:”、または同様の)編集
    • トリックを明確にするために回答を再定式化しました(つまり、シェルパイプラインを動的に構築します)

    回答

    git grep

    git grep ブール式を使用して複数のパターンを組み合わせる:

    git grep --no-index -e pattern1 --and -e pattern2 --and -e pattern3 

    上記のコマンドは、すべてのパターンに一致する行を一度に出力します。

    --no-index Gitによって管理されていない現在のディレクトリ内のファイルを検索します。

    man git-grepヘルプが必要です。

    関連項目:

    またはの操作については、以下を参照してください。

    コメント

    • すばらしい答えです。ありがとうございます。

    回答

    これが私の見解です。これは、複数行の単語に対して機能します。

    find . -type fの後に
    -exec grep -q "first_word" {} \;
    を使用し、最後のキーワードを
    -exec grep -l "nth_word" {} \;

    -q静か/サイレント
    -lファイルを表示一致するもの

    以下は、「rabbit」と「hole」という単語が含まれるファイル名のリストを返します。
    find . -type f -exec grep -q "rabbit" {} \; -exec grep -l "hole" {} \;

    コメント

    • 注意深く見ると、これは質問が求めている機能ではないことがわかるかもしれません。

    回答

    ripgrep

    rg を使用した例:

    rg -N "(?P<p1>.*pattern1.*)(?P<p2>.*pattern2.*)(?P<p3>.*pattern3.*)" file.txt 

    Rustの正規表現エンジン。有限オートマトン、SIMD、積極的なリテラル最適化を使用して検索を非常に高速化します。

    GH-875

    回答

    単語(またはパターン)のすべてを見つけるには、forループでgrepを実行します。ここでの主な利点は、正規表現のリストから検索することです。

    実際の例:

    # File "search_all_regex_and_error_if_missing.sh" find_list="\ ^a+$ \ ^b+$ \ ^h+$ \ ^d+$ \ " for item in $find_list; do if grep -E "$item" file_to_search_within.txt then echo "$item found in file." else echo "Error: $item not found in file. Exiting!" exit 1 fi done 

    このファイルで実行してみましょう:

    hhhhhhhhhh aaaaaaa bbbbbbbbb ababbabaabbaaa ccccccc dsfsdf bbbb cccdd aa caa 
    $ ./search_all_regex_and_error_if_missing.sh aaaaaaa aa ^a+$ found in file. bbbbbbbbb bbbb ^b+$ found in file. hhhhhhhhhh ^h+$ found in file. Error: ^d+$ not found in file. Exiting! 

    コメント

    • ロジックに問題があります-ALL演算子、コードはOR演算子として機能し、ANDとしては機能しません。そのために(OR)は、質問で正しく与えられたはるかに簡単な解決策です。
    • @greenoldmanロジックは単純です:forはすべての単語/パターンでループしますがリストにあり、ファイルで見つかった場合は印刷されます。したがって、単語が見つからなかった場合にアクションが必要ない場合は、elseを削除してください。’ / li>
    • あなたのロジックと私の質問を理解しています-AND演算子について質問していました。つまり、ファイルがパターンAとパターンに一致する場合にのみポジティブヒットになります。 BとパターンCと… ANDこの場合、ファイルは正のヒットになります。パターンAまたはパターンBまたは…違いがわかりますか?
    • @greenoldmanこのループがすべてのパターンのAND条件をチェックしないと思う理由がわかりませんか?そこで、’実際の例を使用して回答を編集しました。ファイル内でリストのすべての正規表現を検索し、最初に欠落している正規表現ではエラーで終了します。
    • 目の前にあり、最初の試合が実行された直後にポジティブマッチがあります。 ” collect “すべての結果を取得し、それらに対してANDを計算する必要があります。次に、複数のファイルで実行するようにスクリプトを書き直す必要があります。そうすると、質問がすでに回答されていて、テーブルに何も表示されないことに気付くかもしれません。

    コメントを残す

    メールアドレスが公開されることはありません。 * が付いている欄は必須項目です