Grep 正则表达式未按预期工作
Posted
技术标签:
【中文标题】Grep 正则表达式未按预期工作【英文标题】:Grep regular expression not working as expected 【发布时间】:2022-01-02 18:27:46 【问题描述】:我有一个简单的grep
命令试图只获取 CSV 文件的第一列,包括逗号。是这样的……
grep -Eo '^[^,]+,' some.csv
所以在我的脑海中,这读起来就像“只给我匹配的部分,每行至少以一个不是逗号的字符开头,然后是一个逗号。”
所以在文件some.csv
上,看起来像这样:
column1,column2,column3,column4
column1,column2,column3,column4
column1,column2,column3,column4
我期待这个输出:
column1,
column1,
column1,
但是我得到了这个输出:
column1,
column2,
column3,
column1,
column2,
column3,
column1,
column2,
column3,
这是为什么呢? 我的 grep/regex 缺少什么?我的预期输出不正确吗?
如果我删除正则表达式中尾随逗号的要求,该命令将按预期工作。
grep -Eo '^[^,]+' some.csv
给我:
column1
column1
column1
注意:我在 macOS High Sierra 上使用 grep 版本:grep (BSD grep) 2.5.1-FreeBSD
【问题讨论】:
这不是与 GNU grep 的唯一区别。如果您看到更多这样的差异,just install GNU grep 可能比works as expected 更好。 我看到了一些与 BSD grep 中的错误有关的问题... 1) unix.stackexchange.com/questions/352977/… 2) unix.stackexchange.com/questions/398223/… 3) unix.stackexchange.com/questions/428340/… .. 解决方法可能是改用 sed/awk 包括 awk 在内的 BSD 工具有问题,最好尽量避免。获取 GNU 工具。话虽如此,即使是BSD sed 也应该能够处理sed 's/^\([^,]*,\).*/\1/' file
【参考方案1】:
BSD grep
通常是错误的。请参阅以下相关帖子:
上面的最后一个链接提到了您的情况:当使用 -o
选项时,grep
出于某种原因忽略了 ^
锚点。这个问题也在FreeBSD bug中描述:
我注意到相同版本的 grep 存在更多问题。我不 知道它们是否相关,但我现在将它们附加到这里。
$ printf abc | grep -o '^[a-c]'
应该只打印'a',而是针对每个字母给出三个命中 传入的文本。
作为一种解决方法,最好只安装GNU grep 而不是works as expected。
或者,使用带有 BRE POSIX 模式的 sed
:
sed -i '' 's/^\([^,]*,\).*/\1/' file
模式匹配的地方
^
- 行首
\([^,]*,\)
- 第 1 组(后来用 RHS 的 \1
反向引用引用):
[^,]*
- 除了,
之外的零个或多个字符
,
- 一个 ,
字符
.*
- 该行的其余部分。
请注意,-i
将就地更改文件内容。如果需要,请使用 -i.bak
创建备份文件(不过,您将不需要下一个空的 ''
)。
【讨论】:
Mac 没有附带 BSD grep,它带有 GNU grep 2.5 - 最后一个 GPL2 许可的 GNU grep。我无法在 FreeBSD 上重现该问题。 FreeBSD 曾经使用过 GNU grep,因此出现了 2012 年的错误报告。以上是关于Grep 正则表达式未按预期工作的主要内容,如果未能解决你的问题,请参考以下文章