簡體   English   中英

如何將僅包含模式的單個實例的行與 grep 匹配?

[英]How can I match a line containing only a single instance of a pattern with grep?

給定一個像這樣的文本文件,說phrases.txt的內容:

Hahahahahasdhfjshfjshdhfjhdf
Hahahaha!
jdsahjhshfjhfHahahaha!dhsjfhajhfjhf
Hahaha!Hahaha!
dfhjfsf
sdfjsjf Hahaha! djfhjsdfh
Ha! hdfshdfs
Ha! Ha! Ha!

什么是 bash 中合適的grep命令,它只輸出僅包含一次大笑的行,其中大笑被定義為Hahahahaha!形式的字符串Hahahahaha! 有任意多的ha 第一個H總是大寫,其他的不是,並且字符串必須以! . 在我的示例中, egrep 命令應該輸出:

Hahahaha!
jdsahjhshfjhfHahahaha!dhsjfhajhfjhf
sdfjsjf Hahaha! djfhjsdfh
Ha! hdfshdfs

我想出的命令是:

egrep "(Ha(ha)*\!){1}" phrases.txt

我的命令的問題在於它不僅輸出只有一次笑聲的行。 使用我的命令,第 4 行( Hahaha!Hahaha! )和第 8 行( Ha! Ha! Ha! )也被打印出來,這不是我想要的。

有沒有一種只用 grep 來做到這一點的好方法?

那么你對管道沒問題

egrep '(Ha(ha)*!)' yourfile.txt | egrep -v '(Ha(ha)*!).*(Ha(ha)*!)'

首先過濾至少一個笑聲,然后過濾掉不止一個笑聲的那些。

注意: {1}只重復前一個塊,它不會檢查字符串的其余部分以堅持只有一個。 所以a{1}a實際上是一樣的。

如果您使用支持 PCRE 正則表達式的 GNU greppcregrep ,您可以使用

grep -P '^(?!(?:.*Ha(ha)*!){2}).*Ha(ha)*!'

圖案是:

^(?!(?:.*YOUR_PATTERN_HERE){2}).*YOUR_PATTERN_HERE

其中YOUR_PATTERN_HERE代表您希望在字符串中只出現一次的模式。

細節

  • ^ - 字符串的開始
  • (?!(?:.*YOUR_PATTERN_HERE){2}) - 匹配失敗的負向前瞻,緊靠當前位置(這里是字符串的開頭)的右側,連續出現兩次
    • .* - 除換行符以外的任何 0+ 個字符
    • YOUR_PATTERN_HERE - 您需要的模式
  • .* - 除換行符以外的任何 0+ 個字符
  • YOUR_PATTERN_HERE - 您所需的模式。

請參閱在線演示

s="Hahahahahasdhfjshfjshdhfjhdf
Hahahaha!
jdsahjhshfjhfHahahaha!dhsjfhajhfjhf
Hahaha!Hahaha!
dfhjfsf
sdfjsjf Hahaha! djfhjsdfh
Ha! hdfshdfs
Ha! Ha! Ha!"
echo "$s" | grep -P '^(?!(?:.*Ha(ha)*!){2}).*Ha(ha)*!'

輸出:

Hahahaha!
jdsahjhshfjhfHahahaha!dhsjfhajhfjhf
sdfjsjf Hahaha! djfhjsdfh
Ha! hdfshdfs

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM