2009-09-14 44 views
5

有沒有一種簡單的方法使用grep(或與其他標準命令行工具結合)來獲取包含一個模式但沒有第二個模式的所有文件的列表?如何使用grep查找包含一個模式但沒有第二個模式的所有文件?

在我的特定情況下,我想包含模式的所有文件的列表:

override.*commitProperties 

但不包含:

super.commitProperties 

我在Windows,但cygwin的廣泛使用。我知道如何找到第一個模式的所有文件或沒有第二個模式的所有模式,但我不知道如何組合這些查詢。

我更喜歡那些通用的答案,因爲我有很多其他人可以找到這種類型的查詢有用。對於我來說,採取一個通用的解決方案並插入我的價值是很容易的。我只是包含了我的具體實例以使解釋更容易。

+0

你不能管第一個模式匹配輸出到第二個,然後做一個grep那裏的第二個模式? – vpram86 2009-09-14 15:33:51

+1

否 - 圖案可能在不同的線上 – DVK 2009-09-14 15:40:54

+0

@ DVk-哦! :)我忘記了。非常感謝! – vpram86 2009-09-14 15:42:46

回答

10
grep -rl "override.*commitProperties" . | xargs grep -L "super.commitProperties" 

-l打印用火柴文件

-L打印不匹配

+0

這個和hlovdal都有效,但我更喜歡這個,因爲它更簡單。 – Herms 2009-09-14 15:56:14

+0

一個人可以通過調用「superXcommitProperties」來逃避一個做grep的人的憤怒以找到邪惡的代碼;-) – 2009-09-14 15:56:45

+0

邪惡的代碼?不,不。這是我忘了在幾個地方添加超級電話給我的覆蓋的情況,導致奇怪的事情發生。我已經很好地毆打自己,現在我只是在尋找所有我弄糟的地方,以便我能夠解決它。 :) – Herms 2009-09-14 16:01:32

4

嘗試

find . -print0 | xargs -0 grep -l "override.*commitProperties" \ 
| tr '\012' '\000' | xargs -0 grep -L super.commitProperties 

tr命令將換行轉換爲ascii空,這樣就可以使用在第二xargs的-0,避免與文件名等

測試結果空間的所有問題:

/tmp/test>more 1 2 3 | cat 
:::::::::::::: 
1 
:::::::::::::: 
override.*commitProperties 
super.commitProperties 
:::::::::::::: 
2 
:::::::::::::: 
override.*commitProperties 
:::::::::::::: 
3 
:::::::::::::: 
hello world 
/tmp/test>find . -print0 | xargs -0 grep -l "override.*commitProperties" | tr '\012' '\000' | xargs -0 grep -L super.commitProperties 
./2 
/tmp/test> 

正如由Douglas指出,查找+ xargs的可以被取代的grep -r

+0

這幾乎是我所建議的,除了我已經使用rep -r而不是查找。 – 2009-09-14 15:37:24

+0

你可以添加一些關於每個命令在做什麼的細節?我得到了find和grep,但是tr在做什麼? – Herms 2009-09-14 15:43:32

+0

另外,爲什麼找到? grep -r處理遞歸路徑並使其更簡單。以某種方式找到更好的工作嗎? – Herms 2009-09-14 15:44:16

2

使用2 greps和comm的組合,如下所示(模式是A和B)。請注意,由於模式可能位於不同的線路上,因此管道grep不起作用。

$ cat a 
A 
$ cat b 
B 
$ cat ab 
A 
B 

$ grep -l A * > A.only 
$ grep -l B * > B.only 

$ comm -23 A.only B.only 
a 

注意:comm命令打印兩個文件共有或唯一的行。 「-23」打印第一個文件唯一的行 - 從而抑制第二個文件中的文件名。

+2

以前從未運行過comm命令。我更喜歡這種情況下的grep解決方案,因爲它不需要額外的文件,我會忘記刪除,但我很高興你發佈了這個。總是很好地瞭解新命令。 – Herms 2009-09-14 15:59:23

+0

我可能是錯的,但我認爲第一個解決方案(使用xargs)將執行很多grep命令 - 對於您找到的每個文件。 雖然對於小配置文件檢查來說這不是一個問題,但如果您需要通過啓動許多grep子進程來針對一大組文件執行相同的邏輯,那麼這將成爲主要的資源消耗。 – DVK 2009-09-14 16:03:57

+0

請參閱我對接受的解決方案的評論。我不相信任何超過2個greps將會被啓動。 – Herms 2009-09-14 17:04:08

2

我的解決方案類似於道格拉斯Leeder介紹的,但我不使用xargs的文件:

grep -l 'override.*commitProperties' $(grep -L super.commitProperties *.txt) 

grep -L命令產品列出的文件不包含模式n super.commitPropertiesgrep -l命令查找*覆蓋。 commitProperties註銷該列表。

總的來說,它是一種不同的方式來皮膚的貓。

+0

我對這種語法不熟悉。 $()在做什麼? – Herms 2009-09-22 14:17:46

+0

$(command)語法本質上是反引號語法:'command'。 shell用其輸出替換$(command)或'command)'。你可以谷歌「bash命令替換」瞭解更多信息 – 2009-09-22 15:10:13

1

ack -l --make "override.*commitProperties" | xargs ack -L "super.commitProperties"

我用這個線程,並試圖做一個遞歸查詢。這需要25分鐘+所以找出約ack。在5分鐘內完成。

方便的工具ack

0
grep "override.*commitProperties" *| grep -v "super.commitProperties" | cut -d":" -f1 
相關問題