GREP + REGEX 没有像我预期的那样工作

Sur*_*ter 8 grep arch-linux regular-expression

我试图从 ls /dev 获取输出以匹配以 1-4 之间的数字结尾的“tty”。

所以从:

tty5
tty4
tty2
tty6
tty1
Run Code Online (Sandbox Code Playgroud)

应该匹配:

tty4
tty2
tty1
Run Code Online (Sandbox Code Playgroud)

正则表达式

"\s([tty]+[0-4])\s"
Run Code Online (Sandbox Code Playgroud)

RegExr 中工作

我试过在 grep 中使用它:

ls /dev | grep -E \s([tty]+[0-4])\s

ls /dev | grep -E \s([tty]\+\[0-4])\s

ls /dev | grep -Ex \s([tty]+[0-4])\s

ls /dev | grep -P \s([tty]+[0-4])\s
Run Code Online (Sandbox Code Playgroud)

正如我在其他帖子中读到的那样,我仍然无法使其工作。

ter*_*don 31

它不匹配的原因是因为您\s在字符串之前tty和匹配结束时寻找空格 ( ) 。这在这里永远不会发生,因为ls每行会打印一个条目。请注意,ls这与ls | command. 当输出 的ls管道时,会激活该-1选项,导致ls每行仅打印一个条目。如果您只是删除那些,它将按预期工作\s

ls /dev | grep -E '([tty]+[0-4])'
Run Code Online (Sandbox Code Playgroud)

但是,这也将匹配您不想要的各种事物。那个正则表达式根本不是你需要的。该[ ]字符类。该表达式[tty]+等效于[ty]+并且将匹配一个或多个tor y。这意味着它将匹配t,or tttttttttttttttt, ortytytytytytytytytyt或这些字母中的一个或两个的任何其他组合。此外,括号在这里毫无意义,它们构成了一个捕获组,但您没有使用它。你想要的是这个:

$ ls /dev | grep '^tty[0-4]$'
tty0
tty1
tty2
tty3
tty4
Run Code Online (Sandbox Code Playgroud)

注意我是如何在$那里添加的。这是如此的表达只匹配tty,然后一个数,一个1,2,3或4,直到行末($)。

当然,避免所有解析危险ls的安全方法是使用 globs 代替:

$ ls /dev/tty[0-4]
/dev/tty0  /dev/tty1  /dev/tty2  /dev/tty3  /dev/tty4
Run Code Online (Sandbox Code Playgroud)

要不就

$ echo /dev/tty[0-4]
/dev/tty0 /dev/tty1 /dev/tty2 /dev/tty3 /dev/tty4
Run Code Online (Sandbox Code Playgroud)

  • 还有`/dev/tty{1..4}` :) (2认同)

Pan*_*nki 7

该正则表达式似乎有点过于复杂。此外,您应该使用引用!

$ ls /dev | grep -E "tty[1-4]$"
tty1
tty2
tty3
tty4
Run Code Online (Sandbox Code Playgroud)

但是,您绝对应该阅读以下内容:为什么*不*解析`ls`(以及该怎么做)?

  • 大多数正则表达式引擎彼此都有点不同。甚至 regexr 也支持右上角菜单中的“Javascript”和“PCRE”变体。此外,grep 通过`grep` 和`grep -E`(与`egrep` 相同)支持两种不同的变体。这四个都在某种程度上有所不同。`grep -P` 与 PCRE 相同。 (2认同)