そしてに grep を使用した式では、2 つの呼び出しが必要です:
grep -Ei "search term" | grep -Eiv "exclude term"
検索する用語が正規表現でない場合は、固定文字列一致 (-F
) どちらが速いか:
grep -F "search term" | grep -Fv "exclude term"
grep を 2 回呼び出す以外に、これを達成するために考えられる方法は 1 つしかありません。これには、Perl 互換正規表現 (PCRE) と、ややハックなルックアラウンド アサーションが含まれます。
foo を検索するには bar を含む一致を除外 、使用できます:
grep -P '(?=^((?!bar).)*$)foo'
仕組みは次のとおりです。
-
(?!bar)
bar 以外のものに一致します 文字列から文字を消費することなく。次に.
1 文字を消費します。 -
^((?!bar).)*
上記を文字列の先頭から繰り返します (^
) の最後まで ($
)。bar
の場合は失敗します(?!bar)
以降、任意の時点で検出されます 一致しません。 -
(?=^((?!bar).)*$)
文字列の文字を消費することなく、文字列が前のパターンと一致することを確認します。 -
foo
foo を検索します いつものように。
単語を含まない文字列に一致する正規表現でこのハックを見つけましたか?. Bart Kiers の回答では、否定的な先読みがどのように機能するかについて、より詳細な説明を見つけることができます。
これを 1 回のパスで実行したい場合は、grep の代わりに awk を使用できます。
フォーマット:
echo "some text" | awk '/pattern to match/ && !/pattern to exclude/'
例:
echo "hello there" | awk '/hello/ && !/there/'
何も返しません。
echo "hello thre" | awk '/hello/ && !/there/'
戻り値:こんにちは 3
echo "hllo there" | awk '/hello/ && !/there/'
何も返しません。
パターンが複数ある場合は、括弧を使用してグループ化できます。
例:
echo "hello thre" | awk '(/hello/ || /hi/) && !/there/'
戻り値:こんにちは 3
echo "hi thre" | awk '(/hello/ || /hi/) && !/there/'
戻り値:こんにちは
echo "hello there" | awk '(/hello/ || /hi/) && !/there/'
何も返しません。
echo "hi there" | awk '(/hello/ || /hi/) && !/there/'
何も返しません。