人:
我很难判断何时逃避shell中的特殊字符,以及哪些字符应该被转义。例如:
sed '/[0-9]\{3\}/d' filename.txt
如上所述,为什么我们应该逃避 {,同时离开 [不变,我认为它们都是特殊字符。
你能帮帮我吗?
/ BR
ruan
答案 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级别使用\(
或(
。
这样:
让我们很高兴使用BASH / KSH shell和posix或GNU sed中的sed脚本的双引号创建\{
&/$IFS
的替代sed顺序(文字,而不是IFS值)。