暗黙的な 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>
正確に、は、a
とb
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
。
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==FNR
をFILENAME==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
を計算する必要があります。次に、複数のファイルで実行するようにスクリプトを書き直す必要があります。そうすると、質問がすでに回答されていて、テーブルに何も表示されないことに気付くかもしれません。
foo
を含む行とbar