sed(bash)对正则表达式的解释与其他任何工具都不一样?

时间:2019-06-09 14:23:33

标签: regex sed

我正在使用 sed 清理包含单词频率的100MB文本文件。

为了测试我的作品,我使用以下简短示例:

86501.522305    .
30876.406478    yes
15806.203945    no
15397.078939    what
9461.059877     8
10526.408684    ,

空格是单个制表符。 我的目标是清空所有带有“非单词”的行,即行1、5和6。

我的正则表达式

^\S*?\t[\W\d]+$ 
Regex101和Notepad ++上进行测试时,

可以正常工作,但是我的sed命令

sed -ri 's/^\S*?\t[\W\d]+$//g' sample.txt

使文件保持完全不变(文件元数据除外)。

有人知道什么会导致这种奇怪的行为吗?

我检查了文档中的扩展正则表达式,并尝试转义各种字符,但没有成功。

1 个答案:

答案 0 :(得分:2)

关于sed的行为没有什么奇怪的,您只是误解了有多种不同形式的regexp和多种工具以不同的方式和不同的警告以不同的方式支持其中的某些/全部。

默认情况下,

sed支持POSIX BRE,而您的正则表达式包含带有一堆非POSIX扩展名的PCRE(不是ERE)。 GNU和OSX / BSD sed支持带有-E参数的ERE(旧的GNU sed使用-r),而GNU sed支持某些扩展-我希望\ S甚至\ W可以工作,但\ d不能工作。 sed不支持PCRE。

FWIW为了清晰,高效,可移植性等原因,我将使用awk:

$ awk '{print ($NF ~ /[[:alnum:]_]/ ? $0 : "")}' file | cat -n
     1
     2  30876.406478    yes
     3  15806.203945    no
     4  15397.078939    what
     5  9461.059877     8
     6

这将与每个UNIX框上任何shell中的任何awk一起使用。 | cat -n只是显示行已清空而不是删除。