何时逃避shell中的特殊字符

时间:2014-02-27 02:41:05

标签: regex linux shell sed

人:
我很难判断何时逃避shell中的特殊字符,以及哪些字符应该被转义。例如:

sed '/[0-9]\{3\}/d' filename.txt  

如上所述,为什么我们应该逃避 {,同时离开 [不变,我认为它们都是特殊字符。
你能帮帮我吗?

/ BR
ruan

4 个答案:

答案 0 :(得分:1)

此行为的差异仅与sed有关。

在常规模式下,sed仅支持非常基本的正则表达式,因此{字面上是匹配的,除非你注意到转义。

sed '/[0-9]\{3\}/d'

在扩展正则表达式模式下,[ and {都不需要转义:

sed -r '/[0-9]{3}/d'

OSX上的OR:

sed -E '/[0-9]{3}/d'

[ and ]被认为是常规和扩展正则表达式模式中的一个字符类(即使shell的glob模式支持它)

答案 1 :(得分:1)

一般的答案是,当你想将它们视为文字字符而不是它们的特殊含义时,你需要转义具有特殊含义的字符。什么字符具有特殊含义的规则因程序而异。


您的具体问题涉及对sed有特殊意义的字符;单引号可防止bash解释任何包含的字符。

在这种情况下,您要转发{}以阻止sed解释它们。首先,请考虑以下命令:

sed '/[0-9]{3}/d' filename.txt

如果您使用的sed版本专门同时处理[{,则此命令会删除包含正好3位数序列的任何行。 [0-9]不是文字的5个字符的字符串;它是一个匹配任何单个数字的正则表达式。 {3}不是一个3字符的字符串;它是一个与前面正则表达式完全匹配的修饰语。将匹配以下行:

593
3296

但不是

34a7

因为一行中没有3位数。

现在,考虑一下你的命令:

sed '/[0-9]\{3\}/d' filename.txt

[0-9]仍然是与单个数字匹配的正则表达式。但是现在,你已经逃过了大括号。 sed不会将其作为前一个正则表达式的修饰符,而是将其视为文字字符{3}。所以它将匹配以下行:

0{3}
1{3}
5{3}

但不是像

这样的行
346

因为没有大括号。

答案 2 :(得分:0)

我认为您的问题与正则表达式中的特殊字符有关。看看这个:

http://pubs.opengroup.org/onlinepubs/9699919799/basedefs/V1_chap09.html#tag_09_03

答案 3 :(得分:0)

它主要依赖于sed版本(posix兼容或扩展行为),然后你需要根据shell进行调整,因为实际上,在你收到sed动作之前会发生一些修改。最好的例子是在shell级别使用简单的双引号,在sed级别使用\((。 这样:

  1. 定义您想要的模式(reg ex)
  2. 适应您正在使用的sed版本/选项
  3. 适应贝壳解释
  4. 让我们很高兴使用BASH / KSH shell和posix或GNU sed中的sed脚本的双引号创建\{ &/$IFS的替代sed顺序(文字,而不是IFS值)。