【问题标题】:Regular expression operator {} in linux bashlinux bash中的正则表达式运算符{}
【发布时间】:2022-01-22 20:23:30
【问题描述】:

{} 运算符有一些问题。在以下示例中,我试图查找出现 1、2 和 2 次或更多单词 mint 的行,但只有在搜索 1 出现 mint 时才会得到响应,甚至虽然每行有超过1

我正在处理的输入是通过ls -l 命令获得的类似列表:

-rw-r--r--  1 mint mint   26 Dec 20 21:11 example.txt
-rw-r--r--  1 mint mint   26 Dec 20 21:11 another.example
-rw-r--r--  1 mint mint   19 Dec 20 15:11 something.else
-rw-r--r--  1 mint mint    1 Dec 20 01:23 filemint
-rw-r--r--  1 mint mint   26 Dec 20 21:11 mint

使用ls -l | grep -E 'mint{1}',我找到了上面的所有行,但我预计什么也找不到(应该是所有出现 1 次mint 的行)。

ls -l | grep -E 'mint{2}' 我什么也没找到,我希望能找到上面的前 3 行(应该是所有出现 2 次 mint 的行)。

对于ls -l | grep -E 'mint{2,}',我希望能找到上面的所有行,但我又什么也没找到(应该是所有行至少出现 2 次 mint)。

我是否遗漏了 {} 的工作原理?

【问题讨论】:

标签: regex linux bash grep


【解决方案1】:

首先,正则表达式中的“量词”指的是紧接在其前面的“标记”,默认情况下是单个字符。所以mint{2} 正在寻找字符t 两次——它相当于m{1}i{1}n{1}t{2}mintt

要多次搜索字符序列,您需要使用括号分组该序列。所以(mint){2} 将连续两次搜索序列mint,如mintmint

其次,在您的输入中,在mint 的出现之间有额外的字符;正则表达式需要指定那些是允许的。

最简单的方法是使用模式.*,意思是“任何事情,零次或多次”。这会给你(mint.*){2},它将匹配“mint 后跟任何内容,两次”。

最后,给定输入“mint mint”,模式(mint.*){1} 将匹配 - 它并不关心某些“额外”字符是否也拼写“mint”,它只知道必需的部分在那里。事实上,{1} 总是多余的,(mint.*){1} 匹配的内容与 mint 匹配的内容完全相同。一般来说,正则表达式擅长断言那里的,而不是断言那里的

一些正则表达式风格具有“前瞻断言”,可以处理否定断言,例如“不跟随mint”,但grep -E 没有。它有一个开关-v,它反转整个命令 - 它显示所有行除了与正则表达式匹配的行。因此,说“mint 的实例不超过 1 个”的简单方法是运行 grep 两次 - 一次正常,一次使用 -v

# At least once, but not twice -> exactly once
ls -l | grep -E 'mint' | grep -v -E '(mint.*){2}'

# At least twice, but not three times -> exactly twice
ls -l | grep -E '(mint.*){2}' | grep -v -E '(mint.*){3}'

【讨论】:

    猜你喜欢
    • 2013-10-26
    • 1970-01-01
    • 2014-03-17
    • 2012-10-30
    • 1970-01-01
    • 1970-01-01
    • 2012-02-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多