2014-08-31 85 views
1

我正在嘗試搜索包含'foo'的行,但這些行不得包含'bar'。用ack這些參數進行搜索的好方法是什麼?如何用ack指定忽略模式?

我可以這樣做:

ack "foo" | grep -v "bar"

,但它不保存ack的漂亮疊合了和彩色輸出。此外,與ack不同,grep不支持Perl正則表達式。

+0

@TomFenech是的,非常抱歉。我在發佈問題後出於某種原因糾正了幾分鐘,但沒有持續。 – DBedrenko 2014-08-31 09:48:21

+0

你不能使用'awk'?它會輕鬆做到這一點。 – Jotne 2014-08-31 10:12:57

+0

@Jotne'ack'更適合搜索文本文件,特別是源代碼,並且有很多適合這個特性的特性,使它成爲比awk更好的工具。例如'awk'只支持POSIX ERE,這對我來說是一種破壞行爲;另一方面,'ack'支持Perl正則表達式。 – DBedrenko 2014-08-31 10:18:26

回答

4

您可以使用一個稍微複雜的正則表達式:

ack '^(?!.*bar).*(foo)' file 

(?!...)做了負前瞻,以確保「吧」是不是就行了。以下是它的工作方式:

  • ^從行首開始。
  • (?!.*bar)前進任意數量的字符,直到找到「bar」。如果發現,請不要繼續。否則,返回到行首並繼續。
  • .*(foo)匹配(和捕捉)「foo」在行的開始和結束之間的任何點。

測試出來:

$ cat file 
other foo bar 
baz foo other 
$ ack '^(?!.*bar).*(foo)' file 
baz foo other 
+0

與@ jcl的答案不同的建議不同,這隻突出搜索詞而不是整行。我可以嘗試用某種方法制作一個'ack'包裝,這樣我就不必輸入那麼長的正則表達式。謝謝! – DBedrenko 2014-08-31 10:13:44

+1

沒問題。只有單詞被突出顯示的原因是因爲我已經將它包含在捕獲組「(foo)」中。如果刪除括號,則整行將突出顯示。 – 2014-08-31 10:16:54

+0

請你能解釋爲什麼帶有「酒吧」的線條會被忽略,即使它們的位置在「foo」之後?我認爲,後面看起來*匹配模式。 – DBedrenko 2014-08-31 10:29:58

4

一種可能性是使用ack本身的排斥通,並扭轉調用的順序:

ack -v "bar" | ack "foo" 

至少會突出搜索詞,但它不會讓你完全一樣格式化只是ack "foo"

另一種可能是在同一個正則表達式的兩項打包在一起,使用負前瞻的排除項,因爲在這個答案給出:

Multiple patterns with ack-grep?

ack '^(?!.*bar).*foo.*$' 

,將讓你ack的每個文件格式,但整行將突出顯示爲搜索項。