sed的功能同awk类似,差别在于:sed简单,对列处理的功能要差一些,awk的功能复杂,对列处理的功能比较强大。
只能操作ASCII码,逐行将内容读取到内存中,做处理,并将处理结果输出。这段内存空间被称为“模式空间”。不一定每一行都处理,根据一定的模式匹配某些行进行处理。默认不修改源文件,仅对模式空间数据进行处理,然后将模式空间的内容输出。
常用选项
选项-n :静默模式,只显示匹配到的行
文件test1里的内容是:
!#/bin/bash
echo $1
echo $2
echo $3
echo $4
echo "hello"
例1
[root@localhost ~]# sed "1,3p" -n test1 //打印匹配到的第一到第三行
!#/bin/bash
echo $1
echo $2
例2
[root@localhost ~]# sed '/a/p' -n test1 //打印包含字母a的行
!#/bin/bash
选项-i :编辑源文件
sed默认会把输入行读取到模式空间,简单理解就是一个内存缓冲区,sed子命令处理的内容是模式空间中的内容,而非直接处理文件内容。因此在sed修改模式空间内容之后,并非直接写入修改输入文件,而是打印输出到标准输出。如果需要修改输入文件,那么就可以指定-i选项。
例1
[root@localhost ~]# sed -i 's/echo/hello/' test1
[root@localhost ~]# cat test1
!#/bin/bash
hello $1
hello $2
hello $3
hello $4
hello "hello"
例2
[root@localhost ~]# sed -i.bak 's/echo/hello/' test1
[root@localhost ~]# cat test1.bak
!#/bin/bash
hello $1
hello $2
hello $3
hello $4
hello "hello"
//把修改内容保存到test.bak,同时会以file.txt.bak文件备份原来未修改文件内容,以确保原始文件内容安全性,防止错误操作而无法恢复原来内容。
选项-r :sed命令的匹配模式默认只能支持基本正则表达式,如果需要支持扩展正则表达式,那么需要添加-r选项。
例
[root@localhost ~]# echo "hey huahua" | sed -r 's/(h)|(u)/w/g'
wey wwawwa
//把h或者u替换为w,g表示全局替换
选项-f :子命令较多时,可以把命令写入文件中
例
[root@localhost ~]# cat sed.sh
s/hello/a/
s/world/b/
[root@localhost ~]# echo "hello huahua" | sed -f sed.sh
a huahua
sed命令
d: 删除符合条件的行
p: 显示符合条件的行
[root@localhost ~]# sed '/^root/,/bash$/p' -n /etc/passwd
//表示以root开头,以bash结尾
a: a \string 在指定的行后追加新行
例
[root@localhost ~]# sed '/^hello/a \huahua~' test1 //反斜杠相当于换行符
!#/bin/bash
hello $1
huahua~
hello $2
huahua~
hello $3
huahua~
hello $4
huahua~
hello "hello"
huahua~
i: i \string 在执行的行前面插入新行
例1
[root@localhost ~]# sed '/^hello/i \huahua~' test1 //在前面追加一行
!#/bin/bash
huahua~
hello $1
huahua~
hello $2
huahua~
hello $3
huahua~
hello $4
huahua~
hello "hello"
例2
[root@localhost ~]# sed '/^hello/i \huahua~\naaa' test1 //在前面追加两行
!#/bin/bash
huahua~
aaa
hello $1
huahua~
aaa
hello $2
huahua~
aaa
hello $3
huahua~
aaa
hello $4
huahua~
aaa
hello "hello"
r: r filename 将制定文件的内容,追加到匹配到行之后
例
[root@localhost ~]# cat haha
a b c
[root@localhost ~]# sed '/^hello/r ./haha' test1
!#/bin/bash
hello $1
a b c
hello $2
a b c
hello $3
a b c
hello $4
a b c
hello "hello"
a b c
//在匹配到的行后面读文件
w: w filename 将指定文件的内容,另存为新的文件(覆盖)
例
[root@localhost ~]# sed '/^hello/w /haha' test1
!#/bin/bash
hello $1
hello $2
hello $3
hello $4
hello "hello"
[root@localhost ~]# cat /haha
hello $1
hello $2
hello $3
hello $4
hello "hello"
s: 查找并替换 s/匹配模式/要替换的内容/
例
[root@localhost ~]# sed 's/hello/huahua/' test1
!#/bin/bash
huahua $1
huahua $2
huahua $3
huahua $4
huahua "hello"
[root@localhost ~]# sed '1,3s/hello/huahua/' test1 //指定区间
!#/bin/bash
huahua $1
huahua $2
hello $3
hello $4
hello "hello"
[root@localhost ~]# sed 's/hello/huahua/g' test1 //全局替换
!#/bin/bash
huahua $1
huahua $2
huahua $3
huahua $4
huahua "huahua"
[root@localhost ~]# sed 's/hello/huahua/gi' test1 //忽略大小写
&:(向后引用)表示引用匹配到的整个字符串
例
[root@localhost ~]# cat ap
love
like
flove
f like
[root@localhost ~]# sed 's/l.*e/&x/g' ap
lovex
likex
flovex
f likex
// 先匹配(/总内容/)、再分组,从左往右,从外到里
[root@localhost ~]# sed 's/\(f\)\(l.*e\)/\1x\2y/g' ap
love
like
fxlovey
f like
注意:grep和sed的对比
grep -A 2 root /etc/passwd 显示匹配到行和后两行
sed '2,+1p' /etc/passwd 可以看到后面的行
grep -B 2 root /etc/passwd 显示匹配到行和前两行
sed '2,-1p' /etc/passwd 不能用,不能查看前一行,因为按行匹配,不回头。