使用 grep 查找包含在空格中或从开头或结尾开始的字符串

使用 grep 查找包含在空格中或从开头或结尾开始的字符串

如何匹配一些用空格括起来或来自开头或结尾的字符串?

我需要匹配-someword以下句子:word1 -someword word2, -someword word1, word1 -someword, -someword。并且句子中不需要匹配:s-someword,-somewordd

我尝试用正则表达式 grep 上面的内容grep -r [^ ]-someword[$ ](即之前-someword必须是空格或-someword必须开始句子,之后-someword必须是空格或-someword必须结束句子),但它什么也没找到。

答案1

尝试:

grep -w -e -someword

man grep

-w, --word-正则表达式

          Select only those lines containing matches that form whole
          words.  The test is that the matching substring must
          either be at the beginning of the line, or preceded by a
          non-word constituent character.  Similarly, it must be
          either at the end of the line or followed by a non-word
          constituent character.  Word-constituent characters are
          letters, digits, and the underscore.  This option has no
          effect if -x is also

-someword请注意,如果它被除空格之外的其他非字母数字字符包围,例如#或,它也会匹配,。如果你想确保它被包围仅有的通过空格或行首/行尾,您可以使用:

egrep '(^|[[:space:]])-someword([[:space:]]|$)'

# Which is equivalent to:

grep -E '(^|[[:space:]])-someword([[:space:]]|$)'

# Or without extended regex:

grep '\(^\|[[:space:]]\)-someword\([[:space:]]\|$\)'

答案2

您可以使用以下内容来避免复杂的正则表达式。它匹配-someword开头有空格、-someword中间某处两侧有空格或-someword末尾有空格的任何行:

grep -e '^-someword ' -e ' -someword ' -e ' -someword$'

这一切都假设这-someword是一个不包含任何正则表达式中特殊字符的字符串。如果是,则必须重写字符串以匹配这些文字字符,例如,通过在模式中转义它们。

如果您还想匹配只包含字符串的行-someword,请添加-e '^-someword$'.

如果“空格”的意思是“空白字符”,其中包括制表符和空格,则使用 更改模式中的文字空格[[:blank:]]。如果您需要匹配更广泛的类似空格的字符,例如垂直制表符和回车符,请改用[[:space:]]

答案3

其正则表达式模式是(https://regexr.com/7b8g0):

(\s|^)-someword(\s|$)

很多 shell 都会对这些感到害怕,()\|所以你必须稍微修改一下引号和转义符。例如,fish 似乎喜欢,\\s但 zsh 喜欢\s

使用 ripgrep 和 Fish,实现起来非常容易:

$ bat word.txt --style=numbers
   1 word1 -someword word2
   2 -someword word1
   3 word1 -someword
   4 -someword
   5 s-someword
   6 -somewordd
   7 \s-someword

$ bat word.txt | rg '(\\s|^)-someword(\\s|$)' --only-matching --line-number
1: -someword
2:-someword
3: -someword
4:-someword

$ bat word.txt | rg '(\\s|^)-someword(\\s|$)' --line-number -v
5:s-someword
6:-somewordd
7:\s-someword

(我添加了\s-someword-v来解决评论中的一些问题。)

请注意,空格成为匹配的一部分。要在正则表达式中解决这个问题,您必须在周围添加一个捕获组-someword(简单),然后告诉rg返回第一个组(pffft ...)。

因为 grep 很古老,所以默认情况下它不会处理这种“高级”正则表达式语法。您需要添加-E.

$ bat word.txt | grep -E '(\\s|^)(-someword)(\\s|$)' -n
1:word1 -someword word2
2:-someword word1
3:word1 -someword
4:-someword

$ bat word.txt | grep -v -E '(\\s|^)(-someword)(\\s|$)' -n
5:s-someword
6:-somewordd
7:\s-someword

坦率地说,如果您生活在以 2 开头的年份,那么无论如何您都应该使用grep别名grep -E。或者只是使用rg.

相关内容