Command-Line

grep 字元串,其中下一行不包含字元串

  • August 11, 2019

我想在目錄及其子目錄中的所有文件中搜尋包含某個字元串的行,但我想排除那些在緊隨其後的行中包含不同某個字元串的結果。

例如,這個:

foo1 searchString bar
foo1 excludeString bar

foo2 searchString bar
something else

foo3 searchString bar

foo3 excludeString bar

foo4 searchString bar

應該返回這個:

foo2 searchString bar
foo3 searchString bar
foo4 searchString bar

我知道-A列印多行,並且-v不包括結果。但我目前的做法grep -r -A 1 "searchString" | grep -v "excludeString"顯然行不通。

有沒有辦法告訴第二個 grep 如果找到匹配項,它也應該刪除前一行?或者我可以如何實現這一目標的其他方式?

性能不是我最關心的;如果該命令相對容易記住,那就太好了。

您可以使用perlc兼容的正常rxpressions :e``grep

$ pcregrep -M '(searchString.*\n)(?!.*excludeString)' file
foo2 searchString bar
foo3 searchString bar
foo4 searchString bar

它搜尋searchString後跟任何 char .,重複零次或多次,只有在它旁邊沒有( ) 模式時才*跟新行。存在選項以匹配多行。\n ?!``.*excludeString``-M

sed

sed '/searchString/!d;$!N;/\n.*excludeString/!P;D' infile

這個怎麼運作:

  • /searchString/!d如果不匹配則刪除該行searchString並讀入新行,重新開始命令循環(即不再執行剩餘的命令)
  • 如果該行匹配searchString,則sed執行$!N;/\n.*excludeString/!P;D- 請參閱此處它是如何工作的;不同之處在於,它excludeString在 ewline 字元之後查找模式,\n以便匹配兩者的行,如果後面沒有匹配行searchString,則仍然列印;如果沒有與和(即已知輸入)匹配的行,那麼您可以刪除該部分並執行:excludeString``excludeString``searchString``excludeString``\n.*

sed '/searchString/!d;$!N;/excludeString/!P;D' infile

引用自:https://unix.stackexchange.com/questions/220355