如何使用 grep 搜尋某個單字的出現與不存在

如何使用 grep 搜尋某個單字的出現與不存在

我有一個內容類似以下內容的文件:

google.com,9,AB+CD,nonAB+nonCD
youtube.com,9,AB+CD,AB+CD
facebook.com,20,AB+CD,nonCD

列數不固定。但第一列是 URL,第二列是數字,從第三列開始是用逗號分隔的關鍵字,但它們因網站而異。

我想計算 URL(行)的數量,我可以在其中控制行中的關鍵字。例如,
1)AB+CD沒有nonABnonCD。注意:AB+CD 一詞可以出現多次。 2)AB+CD不出現nonCD(但有其他情況也可以)

如何在一行中搜尋一個字串並確保不存在另一個字串。當我使用時:

grep 'AB+CD' test.txt > result.txt

它列印找到“AB+CD”的每一行。

如果我想列印只有「AB+CD」的行怎麼辦:

youtube.com,9,AB+CD,AB+CD

或有 'AB+CD' 與 'nonAB' 以外的任何其他內容來獲取:

youtube.com,9,AB+CD,AB+CD
facebook.com,20,AB+CD,nonCD

答案1

如果您只想進行純文字搜尋而不關心列,您可以grep -v像這樣連結反向匹配:

cat input.txt | grep 'IncludedText' | grep -v 'ExcludedText'

如果您想按列進行正確的過濾,您需要使用類似awk.

答案2

一般技巧:

  1. 包含foo加號的行包含bar( foo OR bar):

    grep -e foo -e bar
    
  2. foo包含和 的行bar位於同一行 ( foo AND bar):

    grep foo | grep bar
    
  3. 不包含baz( NOT baz) 的行:

    grep -v baz
    

使用這些積木,您可以建立自己的邏輯。問題-v不限於單一模式,它是全局性的grep(至少在我的 Debian 中)。這NOT (foo OR bar)使得:

grep -v -e foo -e bar

這相當於(NOT foo) AND (NOT bar)

grep -v foo | grep -v bar

然而NOT (foo AND bar)(邏輯上等價於(NOT foo) OR (NOT bar))卻不那麼容易。我們可以嘗試foo AND bar獲得單身的(擴展)grep

  1. 再次包含foo和 的行bar位於同一行 ( foo AND bar):

    grep -E 'foo.*bar|bar.*foo'
    

現在得到NOT (foo AND bar)

grep -v -E 'foo.*bar|bar.*foo'

當處理兩個以上模式時,我不確定上面是否是一個完整的系統。但你的問題仍然很少能用它來解決。例子:

AB+CD沒有nonABnonCD

如果我沒猜錯的話就是AB+CD AND NOT (nonAB OR nonCD)

grep AB+CD | grep -v -e nonAB -e nonCD

請注意,這個請求使事情變得複雜:

我想列印只有“AB+CD”的行

有人可能會說grep ,AB+CD,AB+CD可以,但由於“列數不固定”,我想您想區分這兩行:

youtube.com,9,AB+CD,AB+CD,AB+CD
youtube.com,9,AB+CD,AB+CD,banana

在這種情況下,您需要更複雜的正規表示式或其他工具(例如awk)。

答案3

雖然您會在這裡得到答案,但您應該看看人 grep(可能是壓倒性的)和一些例子。目前,答案如下:

使用grep

grep "foobar" test.txt

將搜尋foobar檔案中包含單字的行test.txt並顯示所有出現的情況,而

grep "foo" -v "bar" test.txt

將搜尋包含 wordfoo但不包含 的行bar。我們得到這個是因為-v手冊頁解釋的開關:

-v, --invert-match
    Invert the sense of matching, to select non-matching lines.
    (-v is specified by POSIX .)

它只是意味著它將搜尋包含這些單字的行(這裡bar),但會在最終顯示中排除它們。因此反向搜尋

另外,要計算與搜尋相符的行數,請使用-c轉變 :

-c, --count
    Suppress normal output; instead print a count of matching lines
    for each input file. With the -v, --invert-match option (see below),
    count non-matching lines. (-c is specified by POSIX .)

作為自我練習,嘗試對文件進行 grep 搜索富巴

答案

搜尋AB+CD忽略nonABnonCD計數 URL:

grep "AB+CD" test | grep -cve "non"

where-v "non"會簡單地忽略兩者nonAB和 ,nonCD因為它們都包含non在其中。並-c給出匹配的總數,而不是列印它們。若要列印符合的行,只需忽略-c

您可以將它用於單獨的反轉:

grep "AB+CD" test | grep -cve "nonAB\|nonCD"

其中\|代表OR並且意味著nonAB或者nonCD 精確的指定的單字-e轉變。


建議你看看卡米爾的回答,盡可能多閱讀手冊頁(您知道命令),努力在線搜索內容並為社區服務。請隨意添加更多詳細資訊來回答。

相關內容