私は、文字Ui\.
が続かない、Line
または文字だけでさえないすべてのインスタンスをgrepしようとしていますL
別の文字列が続かない特定の文字列のすべてのインスタンスを検索するための正規表現を作成する適切な方法は何ですか?
先読みの使用
grep "Ui\.(?!L)" *
bash: !L: event not found
grep "Ui\.(?!(Line))" *
nothing
私は、文字Ui\.
が続かない、Line
または文字だけでさえないすべてのインスタンスをgrepしようとしていますL
別の文字列が続かない特定の文字列のすべてのインスタンスを検索するための正規表現を作成する適切な方法は何ですか?
先読みの使用
grep "Ui\.(?!L)" *
bash: !L: event not found
grep "Ui\.(?!(Line))" *
nothing
あなたが求めているものであるネガティブ先読みには、標準よりも強力なツールが必要ですgrep
。PCRE対応のgrepが必要です。
GNUを使用している場合grep
、現在のバージョンはオプションをサポートしています。-P
または--perl-regexp
、必要な正規表現を使用できます。
(十分に新しいバージョンの)GNUがない場合はgrep
、を取得することを検討してack
ください。
あなたの問題の一部に対する答えはここにあります、そしてackは同じように振る舞います: エラーを与えるAckと否定的な先読み
grepに二重引用符を使用しています。これにより、bashは「!
履歴展開コマンドとして解釈」できます。
パターンをSINGLE-QUOTESでラップする必要があります。
grep 'Ui\.(?!L)' *
ただし、標準でのネガティブな先読みの問題に対処するには、@JonathanLefflerの回答grep
を参照してください。
grepを使用して標準のネガティブ先読みを実行することはおそらくできませんが、通常は「逆」スイッチ「-v」を使用して同等の動作を得ることができるはずです。これを使用して、一致させたいものを補完する正規表現を作成し、それを2つのgrepsにパイプすることができます。
問題の正規表現については、次のようなことを行う可能性があります
grep 'Ui\.' * | grep -v 'Ui\.L'
否定の先読みをサポートしない正規表現の実装を使用する必要があり、余分な文字*を一致させてもかまわない場合は、否定の文字クラス[^L]
、交互|
、および文字列アンカーの終わりを$
使用できます。
あなたの場合grep 'Ui\.\([^L]\|$\)' *
は仕事をします。
Ui\.
興味のある文字列と一致します
\([^L]\|$\)
または以外の任意の1文字L
に一致するか、行末に一致します:[^L]
または$
。
複数のキャラクターを除外したい場合は、さらに多くの代替と否定をスローする必要があります。a
後に続くものを見つけるにはbc
:
grep 'a\(\([^b]\|$\)\|\(b\([^c]\|$\)\)\)' *
(a
後にnotb
が続く、または行の終わりが続く:a
then[^b]
または$
)または(a
その後b
にnotc
が続くか、または行の終わりが続く:a
then b
、then[^c]
または$
。
この種の表現は、短い文字列でもかなり扱いにくく、エラーが発生しやすくなります。式を生成するために何かを書くこともできますが、否定的な先読みをサポートする正規表現の実装を使用する方がおそらく簡単でしょう。
*実装が非キャプチャグループをサポートしている場合は、余分な文字をキャプチャすることを回避できます。
少なくとも、「Ui」の後に「L」文字が必要ない場合。あなたは本当にPCREを必要としません。
grep -E 'Ui\.($|[^L])' *
ここでは、「Ui」の特殊なケースと一致するようにしました。行の終わりに。
grepが-Pまたは--perl-regexpをサポートしておらず、PCRE対応のgrep(「pcregrep」など)をインストールできる場合は、Perl互換の正規表現を受け入れるためにGNUgrepなどのコマンドラインオプションは必要ありません。式、あなたはただ走る
pcregrep "Ui\.(?!Line)"
例「Ui。(?!(Line))」のように、「Line」に別のネストされたグループは必要ありません。上記のように、外側のグループで十分です。
否定的なアサーションを探す別の例を挙げましょう。「ipset」によって返される行のリストがあり、各行は行の中央にあるパケットの数を示しており、パケットがゼロの行は必要ありません。走る:
ipset list | pcregrep "packets(?! 0 )"
perl互換の正規表現が好きで、perlはあるが、pcregrepがない場合、またはgrepが--perl-regexpをサポートしていない場合は、grepと同じように機能する1行のperlスクリプトを使用できます。
perl -e "while (<>) {if (/Ui\.(?!Lines)/){print;};}"
Perlはgrepと同じようにstdinを受け入れます。
ipset list | perl -e "while (<>) {if (/packets(?! 0 )/){print;};}"