web-dev-qa-db-ja.com

「用語」のgrepと「別の用語」を除外

用語を検索するが、2番目の用語を含む行を除外するgrep検索を構築しようとしています。複数の-e "pattern"オプションを使用したかったのですが、うまくいきませんでした。

これが私が試したコマンドとそれが生成したエラーメッセージの例です。

grep -i -E "search term" -ev "exclude term"
grep: exclude term: No such file or directory

-vがすべての検索語句/パターンに適用されるように思えます。これは実行されますが、結果にsearch termは含まれません。

grep -i -E "search term" -ve "exclude term"
29
nelaaro

and式をgrepで使用するには、2つの呼び出しが必要です。

grep -Ei "search term" | grep -Eiv "exclude term"

検索する用語が正規表現でない場合は、固定文字列マッチング(-F)高速です:

grep -F "search term" | grep -Fv "exclude term"
41
Thor

Grepを2度呼び出すのではなく、これを実現する方法は1つしかありません。これには Perl互換の正規表現 (PCRE)とかなりハッキーな ルックアラウンドアサーション が含まれます。

fooを検索して、barを含む一致を除外するには、次のように使用できます。

_grep -P '(?=^((?!bar).)*$)foo'
_

仕組みは次のとおりです。

  • _(?!bar)_は、文字列の文字を消費せずにbarでないものに一致します。次に、_._は1文字を消費します。

  • ^((?!bar).)*は、上記を文字列の先頭(_^_)から末尾(_$_)まで繰り返します。 _(?!bar)_は一致しないため、任意の時点でbarが検出されると失敗します。

  • _(?=^((?!bar).)*$)_は、文字列の文字を消費することなく、文字列が前のパターンと一致することを確認します。

  • fooは通常どおりfooを検索します。

私はこのハッキングを 単語を含まない文字列に一致する正規表現? で見つけました。 Bart Kiersの回答 では、否定的な先読みがどのように機能するかについて、より詳細な説明を見つけることができます。

18
Dennis

これを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/'_

戻り値:こんにちは

  • _echo "hllo there" | awk '/hello/ && !/there/'_

何も返しません。

複数のパターンの場合は、括弧を使用してパターンをグループ化できます。

例:

  • echo "hello thre" | awk '(/hello/ || /hi/) && !/there/'

戻り値:こんにちは

  • echo "hi thre" | awk '(/hello/ || /hi/) && !/there/'

戻り値:こんにちは

  • echo "hello there" | awk '(/hello/ || /hi/) && !/there/'

何も返しません。

  • echo "hi there" | awk '(/hello/ || /hi/) && !/there/'

何も返しません。

12
Philip Reese

私の実験では、除外用語をgrepまたはsedを介してパイプしても、大きな違いはありません。 Sedには、他の便利なテキスト置換機能があり、ログファイルの出力をより適切にフィルタリングするためによく使用します。sedにかなりの数のフィルターを組み合わせているため、sedを使用します。

 wc /var/log/Tomcat/tomcat.2013-01-14.log.1 
 1851725 
 
/usr/bin/time grep -i- E "(loginmanager)" /var/log/Tomcat/tomcat.2013-01-14.log.1 | sed -e "/ login OK/d" -e "/ Login expired/d" | wc 
 24.05user 0.15system 0:25.27elapsed 95%CPU(0avgtext + 0avgdata 3504maxresident)k 
 0inputs + 0outputs(0major + 246minor)pagefaults 0swaps 
 5614 91168 1186298 
 
/usr/bin/time grep -i -E "(loginmanager)" /var/log/Tomcat/tomcat.2013-01-14.log.1 | sed -e "/ login OK/d" -e "/ Login expired/d" | wc 
 23.50user 0.16system 0:24.48elapsed 96%CPU(0avgtext + 0avgdata 3504maxresident)k 
 0inputs + 0outputs(0major + 246minor)pagefaults 0swaps 
 5614 91168 1186298 
 
/usr/bin/time grep -i -E "(loginmanager)" /var/log/Tomcat/tomcat.2013-01-14.log.1 | grep -v -e "login OK" -e "Login expired" | wc 
 23.08user 0.14system 0:23.55elapsed 98%CPU(0avgtext + 0avgdata 3504maxresident)k 
 0inputs + 0outputs(0major + 246minor)pagefaults 0swaps 
 5614 91168 1186298 
 
/usr/bin/time grep -i -E "(loginmanager)" /var/log/Tomcat/tomcat.2013-01-14.log.1 | grep -v -e "login OK" -e "Login expired" | wc 
 23.50user 0.15system 0:25.27elapsed 93%CPU(0avgtext + 0avgdata 3488maxresident)k 
 0inputs + 0outputs(0major + 245minor)pagefaults 0swaps 
 5614 91168 1186298 
 
1
nelaaro