共计 1560 个字符,预计需要花费 4 分钟才能阅读完成。
sed
全称:steam editor
单引号 & 双引号 & 反引号
单引号
单引号内的字符都是普通字符,不会有任何特殊意义。包括转义字符。所以会原样输出所有字符
双引号
双引号内的字符,$
,\
,`
这三种字符是有特殊意义的。其中 $
代表了引用变量的值,`
代表了引用的命令。反斜杠是用于转义这两个字符以及双引号本身的。
如果想打印出这几个特殊字符,就需要用转议,否则会失败
# 直接打印,会错误
[root@hadoop usr]# echo "`"
> ^C
#
反引号
反引号括起来的字符串会被识别为命令。其等价于$()
,推荐使用后者,因为反引号容易和单引号混淆。
总结
- 当要匹配的字符串或用于替换的字符串中有单引号时,只能使用双引号包围。
- 当要匹配的或用于替换的含双引号的时候,可以用单引号包围,或用双引号进行包围并使用‘’进行转义
- 在 sed 命令中,引号的解析是 shell 进行的,sed 命令只是获取 shell 解析后的结果。而不同的 shell 解析的方式也可能不同。所以最安全的做法是写在文件中,通过
sed -f
执行,避免了引号的使用。
# 错误用法 -- 双引号下会把 $s 解析成一个变量。所以会报错。sed "1,3s/my/your/g; 3,$s/This/That/g" my.txt
#正确用法 -- 使用单引号,不会做任何解析
sed '1,3s/my/your/g; 3,$s/This/That/g' my.txt
#正确用法 -- 转义 $ 符号
sed "1,3s/my/your/g; 3,\$s/This/That/g" my.txt
匹配行
只替换每一行的第一个 s:
$ sed 's/s/S/1' my.txt
只替换每一行的第二个 s:
$ sed 's/s/S/2' my.txt
只替换第一行的第 3 个以后的 s:
$ sed '1s/s/S/3g' my.txt
特殊符号和命令
1. &
&
用于表示匹配到的结果。
2. 圆括号
使用圆括号匹配的示例:(圆括号括起来的正则表达式所匹配的字符串会可以当成变量来使用,sed 中使用的是 1,2…)
$ sed 's/This is my \([^,&]*\),.*is \(.*\)/\1:\2/g' my.txt
3. BRE & ERE
基本正则表达式 和 扩展正则表达式
反斜杠用于对字符串中特殊字符的转义。在使用圆括号时发现了一点疑问,网上给出的例子都需要对圆括号用 \
进行转义,而这不就是匹配圆括号本身吗?但是在实践中发现,确实当不用转义时会直接匹配字符,只有转义后才会体现括号的作用。
如下面的例子:
#
$ echo "()" | sed 's/()/a/g'
a
#
$ echo "abc" | sed 's/\(b\)/\1\1/g'
abbc
而在之前学正则表达式的时候,是当需要匹配括号本身时才需要转义的。而这就是 基本正则表达式 和 扩展正则表达式 的区别了。
linux 的文本处理命令中,grep
和 sed
都只支持基本正则,而 egrep
和awk
则支持扩展正则。但是 grep
和sed
也可以分别通过 -E
和-r
参数来支持扩展正则
基本正则
基本正则的元字符有以下:
1. ^
2. $
3. .
4. *
5. []
6. \<
7. \>
8. \(\)
9. \?
10.\+
网上很多博客把 ?
和+
归为扩展正则,但是注意在基本正则中,是有这两个符号的,只是要通过转义来使用
在 linux 中测试可以发现这两个元字符都是可以正常使用的。
也有博客说 |
是扩展正则才有的
$ echo "ABC" | sed "s/A\+BC/DDD/"
DDD
$ echo "ABC" | sed "s/A\?BC/DDD/"
DDD
扩展正则
扩展正则只是把一些常用的元字符去掉了转义,并且加了少量新的元字符。
1. +
2. ?
3. ()
所以就明白了为什么在 sed
中的括号要进行转义了。因为 sed
使用的是基本正则,所以要想不用反斜杠直接使用括号,那么加上命令参数 -r
来让 sed
支持扩展正则就可以啦。对于 grep
是一样的道理,可以使用 egrep
或grep -E