web-dev-qa-db-ja.com

いくつかのパターンを除外してgrepする方法は?

あるパターンが発生し、他のパターンが存在しないファイルの行を見つけたいのですが。たとえば、loomを含むものを除く、gloomを含むすべてのファイル/行を検索する必要があります。だから、コマンドでloomを見つけることができます:

grep -n 'loom' ~/projects/**/trunk/src/**/*.@(h|cpp)

ここで、loomを除くgloomを検索します。ただし、次のコマンドは両方とも失敗しました。

grep -v 'gloom' -n 'loom' ~/projects/**/trunk/src/**/*.@(h|cpp)
grep -n 'loom' -v 'gloom' ~/projects/**/trunk/src/**/*.@(h|cpp)

目標を達成するにはどうすればよいですか?

EDIT 1:loomgloomは文字列(必ずしも単語ではない)であることを意味します。したがって、たとえば、コマンド出力にbloombergが必要ですが、ungloomyは必要ありません。

EDIT 2:私の期待のサンプルがあります。次の行は両方ともコマンド出力にあります。

香のベールを通して迫り来るアイコンに直面しました。

Artyはsloominggloomy日です。

次の行は両方ともコマンド出力にありません。

それはグロミインひどいです—偉大なマックルドルダーズoクルード。

Heigh Pyntit Hallの南西ラウンド

69
Loom

Grepsを連結するだけではどうですか?

grep -n 'loom' ~/projects/**/trunk/src/**/*.@(h|cpp) | grep -v 'gloom'
83
houbysoft

grepをチェーン化しない別のソリューション:

egrep '(^|[^g])loom' ~/projects/**/trunk/src/**/*.@(h|cpp)

括弧内では、gが行の最初の文字でない限り、loomが出現する前に文字loomを除外します。

17
Bentoy13

少し古いですが、まあ...

@houbysoftの最もよく投票されたソリューションは、「織機」があっても「gloom」が含まれる行を除外するため、機能しません。 OPの予想によると、「織機」のある行も含める必要があります。この行は「Arty is a slooming in a gloomy day。」の出力にある必要がありますが、これは次のような連鎖grepによって除外されます

grep -n 'loom' ~/projects/**/trunk/src/**/*.@(h|cpp) | grep -v 'gloom'

代わりに、 egrep regex の例 Bentoy1

egrep '(^|[^g])loom' ~/projects/**/trunk/src/**/*.@(h|cpp)

「gloom」があるかどうかに関係なく、「loom」が含まれる行が含まれます。一方、暗がりしかない場合、それは含まれません。これは、OPが望んでいる動作です。

8
Sam

Awkを使用するだけで、複合条件を明確に表現できる点でgrepよりもはるかに簡単です。

loomgloomの両方を含む行をスキップする場合:

awk '/loom/ && !/gloom/{ print FILENAME, FNR, $0 }' ~/projects/**/trunk/src/**/*.@(h|cpp)

またはそれらを印刷する場合:

awk '/(^|[^g])loom/{ print FILENAME, FNR, $0 }' ~/projects/**/trunk/src/**/*.@(h|cpp)

そして、現実がloomが単独でWordとして表示される行が必要な場合:

awk '/\<loom\>/{ print FILENAME, FNR, $0 }' ~/projects/**/trunk/src/**/*.@(h|cpp)
7
Ed Morton

-vは「逆マッチ」フラグなので、パイピングは非常に良い方法です。

grep "loom" ~/projects/**/trunk/src/**/*.@(h|cpp)| grep -v "gloom"

6
Oleg Kokorin

/ *あなたはこのように見えるかもしれませんか?

grep -vn "gloom" `grep -l "loom" ~/projects/**/trunk/src/**/*.@(h|cpp)`

BACKQUOTESはコマンドの括弧のように使用されるため、この場合-lを有効にすると、BACKQUOTESのコードはファイル名を返し、次に-vnを使用して、ファイル名、行番号、および実際の行を指定します。

UPDATEまたはxargsを使用

grep -l "loom" ~/projects/**/trunk/src/**/*.@(h|cpp) | xargs grep -vn "gloom"

お役に立てば幸いです。* /

上に書いたものは無視してください、それはゴミです。

grep -n "loom" `grep -l "loom" tt4.txt` | grep -v "gloom"

               #this part gets the filenames with "loom"
#this part gets the lines with "loom"
                                          #this part gets the linenumber,
                                          #filename and actual line
5
Juto

grep -Pをサポートするnegative lookbehind(Perl正規表現)を使用できます:

grep -P '(?<!g)loom\b' ~/projects/**/trunk/src/**/*.@(h|cpp)

Wordの境界に\bを追加しました。

4
anubhava
grep -n 'loom' ~/projects/**/trunk/src/**/*.@(h|cpp) | grep -v 'gloom'
3
Jiminion

単に使用してください! grep -vを複数回。

ファイルの内容

[root@server]# cat file
1
2
3
4
5

行または一致を除外

[root@server]# cat file |grep -v 3
1
2
4
5

行を除外するか、複数に一致

[root@server]# cat file |grep -v 3 |grep -v 5
1
2
4
1
Tiborcz Kiss

質問:「gloom」を除く「loom」を検索してください。
回答:

grep -w 'loom' ~/projects/**/trunk/src/**/*.@(h|cpp)
0
Abhinandan