为什么这个sed命令输出"[18"而不是"18"?

Gar*_*ook 2 regex unix sed string-substitution

echo [18%] | sed s:[\[%\]]::g
Run Code Online (Sandbox Code Playgroud)

我真的很困惑,因为[18%]在vim中成功替换了相同的模式.我还测试了表达在几个在线的正则表达式的工具,他们都表示,这将匹配的[,%]如预期.我尝试添加-r选项以及在引号中包含替换命令.

我知道还有其他命令可以用来完成这个任务,但我想知道它为什么会这样表现,所以我可以更好地理解sed.

Joh*_*ica 6

$ echo [18%] | sed s:[][%]::g
18
Run Code Online (Sandbox Code Playgroud)

sed支持POSIX.2正则表达式语法:默认为基本(BRE)语法,带-r标志的扩展语法.在POSIX.2语法(基本或扩展)中,通过使其成为字符类中的第一个字符,可以包含右方括号.反斜杠没有帮助.

这很烦人,因为几乎所有其他现代语言和工具都使用Perl或类似Perl的正则表达式语法.POSIX语法是一种时代错误.

您可以在regex(7)手册页中阅读有关POSIX.2语法的内容.

 A bracket expression is a list of  characters  enclosed  in  "[]".   It  normally
 matches  any  single character from the list (but see below).  If the list begins
 with '^', it matches any single character (but see below) not from  the  rest  of
 the  list.  If two characters in the list are separated by '-', this is shorthand
 for the full range of characters between those two (inclusive) in  the  collating
 sequence,  for  example, "[0-9]" in ASCII matches any decimal digit.  It is ille?
 gal(!) for two ranges to share an endpoint, for  example,  "a-c-e".   Ranges  are
 very  collating-sequence-dependent, and portable programs should avoid relying on
 them.

 To include a literal ']' in the list, make it the first  character  (following  a
 possible '^').  To include a literal '-', make it the first or last character, or
 the second endpoint of a range.  To use a literal '-' as the first endpoint of  a
 range,  enclose  it in "[." and ".]"  to make it a collating element (see below).
 With the exception of these and some  combinations  using  '['  (see  next  para?
 graphs), all other special characters, including '\', lose their special signifi?
 cance within a bracket expression.
Run Code Online (Sandbox Code Playgroud)