Linux学习笔记

3次阅读

共计 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 的文本处理命令中,grepsed 都只支持基本正则,而 egrepawk则支持扩展正则。但是 grepsed也可以分别通过 -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 是一样的道理,可以使用 egrepgrep -E

正文完
 0