sed语句语法及命令
什么是sed?
sed(Stream Editor)是一种流式文本编辑器,常用于在命令行环境下对文本进行处理和转换。它按行读取输入文本,根据用户指定的规则进行操作,并将结果输出到标准输出或文件中。sed基于一组命令和正则表达式,可以执行各种文本转换操作,如替换、删除、插入等。
sed的基本语法如下:
sed [options] [script] [input_file]
- options:用于指定
sed
的选项,如-i
用于直接修改原始文件、-n
用于禁止默认输出等。 - script:包含一系列
sed
命令的脚本,用于定义文本处理规则,可以是一个或多个命令组成。- input_file:要处理的输入文件。
sed
的命令由一个地址和一个命令组成,格式为address command
。地址用于指定所应用命令的行范围,命令用于对指定行进行操作。如果省略地址部分,则默认应用于所有行。
下面是一些常用的sed
命令及其功能:
命令 | 用法 |
---|---|
p | 打印 |
s | 替换 |
i | 插入 |
d | 删除 |
a | 在匹配行之后追加文本。 |
c | 更改 |
y | 替换某一个字母 |
n | 表示下一行 |
/n | 表示换行 |
& | 用正则表达式匹配的内容进行替换 |
\ | 转义 |
; | 表示执行下一个命令 |
-n | 关闭默认打印功能,只输出经过处理的行。 |
-i | 直接在原始文件上进行修改(--in-place )。 |
w file | 将经过处理的行写入指定文件。 |
r file | 将指定文件的内容插入到匹配行后。 |
y/chars1/chars2/ | 按字符映射替换。 |
以下是命令的例子
d命令:删除
[root@slave ~]# cat a
2fdasfASfrfgh
rthjdhbds
2356643
dsfsffsdf
werfefew
[root@slave ~]# sed '1d' a //1d表示删除第一行
2rthjdhbds
2356643
dsfsffsdf
werfefew
[root@slave ~]# sed -r '/^2/d' a //正则表达式要加-r /^2/表示匹配2开头的行
rthjdhbds
dsfsffsdf
werfefew
a命令: 追加
[root@slave ~]# cat a
2fdasfASfrfgh
rthjdhbds
2356643
dsfsffsdf
werfefew
[root@slave ~]# sed '1a hello world' a //1a表示在第一行后面追加hello world
22fdasfASfrfgh
hello world
rthjdhbds
2356643
dsfsffsdf
werfefew
[root@slave ~]# sed '/^2/a hello' a //或者匹配2开头的行在后面追加hello
22fdasfASfrfgh
hello
rthjdhbds
2356643
hello
dsfsffsdf
werfefew
i命令: 插入
[root@slave ~]# sed '1i hello world' a //1i表示在第一行前面插入hello world
hello world
22fdasfASfrfgh
rthjdhbds
2356643
dsfsffsdf
werfefew
[root@slave ~]# sed '/^d/i hello' a //或者匹配d开头的行在前面插入hello
22fdasfASfrfgh
rthjdhbds
2356643
hello
dsfsffsdf
werfefew
c命令: 更改
[root@slave ~]# sed '2c hello' a //2c表示把第2行的内容改为hello
22fdasfASfrfgh
hello
rthjdhbds
2356643
dsfsffsdf
werfefew
[root@slave ~]# sed -r '2,4c hello' a //2,4c表示把第二行到第四行改为hello
22fdasfASfrfgh
hello
dsfsffsdf
werfefew
[root@slave ~]# sed -r '2,4c hello\nworld' a //或者改成两行hello(/n表示换行)world
22fdasfASfrfgh
hello
world
dsfsffsdf
werfefew
[root@slave ~]# sed -r '/^2/c hello' a //正则表达式把匹配到的行替换成hello
hello
rthjdhbds
hello
dsfsffsdf
werfefew
s命令 :替换
[root@slave ~]# echo "hello world tom"
hello world tom
[root@slave ~]# echo "hello world tom" | sed -r 's/tom/hello/' # 's/tom/hello/'表示匹配到替换为hello
hello world hello
[root@slave ~]# echo "hello world tom" | sed -r 's/tom/& hello/' #&表示匹配到的东西本身
hello world tom hello
#(.*)表示任意字符串 匹配到hello world在匹配到的东西前面添加hello
[root@slave ~]# echo "hello world tom" | sed -r 's/hello (.*) (.*)/hello &/g'
hello hello world tom
[root@slave ~]# cat ab
.Ah "Major Heading"
[root@slave ~]# sed '/.Ah/s/.Ah/@A HEAD =/' ab #/.Ah/表示匹配含有.Ah的行然后把.Ah替换为@A HEAD =
@A HEAD = "Major Heading"
[root@slave ~]# sed '/.Ah/s/.Ah/@A HEAD =/;s/"//' ab #上一个任务结束后用;结尾然后再匹配”符号替换为空
@A HEAD = Major Heading"
[root@slave ~]# sed '/.Ah/s/.Ah/@A HEAD =/;s/"//g' ab #在最后面加上一个g表示把匹配到的所有“符合都替换为空
@A HEAD = Major Heading
[root@slave ~]# cat ab
.Ah "Major Heading"
see section 1.4
see section 12.9
(see section 12.8)
#把匹配到的内容用引号引起来?表示前面的东西出现零次或一次
[root@slave ~]# sed -r 's/see section [1-9][0-9]?\.[1-9][0-9]?/"&"/' ab
.Ah "Major Heading"
"see section 1.4"
"see section 12.9"
("see section 12.8")
#或者把匹配的内容加上括号就可以把匹配到的括号也引起来
[root@slave ~]# sed -r 's/\(?see section [1-9][0-9]?\.[1-9][0-9]?\)?/"&"/' ab
.Ah "Major Heading"
"see section 1.4"
"see section 12.9"
"(see section 12.8)"
[root@slave ~]# sed -r 's/(.*) (.*) (.*)/\2 \1 \3/' ab #s命令还可以用来更改顺序
"Major .Ah Heading"
section see 1.4
section see 12.9
section (see 12.8)
y命令:替换某一个单词
[root@slave ~]# sed -r 'y/abcdefghyzklmnopqrstuvwxyz/ABCDEFGHYZKLMNOPQRSTUVWXYZ/' ab #把所有小写替换成大写
.AH "MAjOR HEADiNG"
SEE SECTiON 1.4
SEE SECTiON 12.9
(SEE SECTiON 12.8)
p命令 :打印
[root@slave ~]# sed '' ab #sed默认功能就是p打印
.Ah "Major Heading"
see section 1.4
see section 12.9
(see section 12.8)
[root@slave ~]# sed 'p' ab #使用p时会再打印一遍
.Ah "Major Heading"
.Ah "Major Heading"
see section 1.4
see section 1.4
see section 12.9
see section 12.9
(see section 12.8)
(see section 12.8)
[root@slave ~]# sed -n 'p' ab #-n选项关闭默认的打印功能
.Ah "Major Heading"
see section 1.4
see section 12.9
(see section 12.8)
n命令: 表示下一行
[root@slave ~]# sed '/\.Ah/{n;d}' ab #匹配.Ah找到下一行然后删除
.Ah "Major Heading"
see section 12.9
(see section 12.8)
[root@slave ~]#
[root@slave ~]# sed '/\.Ah/{n;/see/s/see/hhh/}' ab #匹配.Ah找到下一行,再匹配这一行的see改see为hhh
.Ah "Major Heading"
hhh section 1.4
see section 12.9
(see section 12.8)
高级sed语句语法集命令
多行模式空间和保持空间
模式空间:sed处理文本内容行的一个临时缓冲区,模式空间中的内容会主动打印到标准输出,并自动清空模式空间,模式空间最多一次性存在两行文本
保持空间:sed处理文本内容行的另一个临时缓冲区,不同的是保持空间内容不会主动清空,也不会主动打印到标准输出,而是需要sed命令来进行处理
模式空间与保持空间的关系
**模式空间:**相当于一个工作室,把我们需要进行操作的文本放入模式空间
保持空间: 相当于一个仓库,用来存放文本
模式空间和保持空间的数据可以互相转换
模式空间每次只存储两行内容
命令 | 功能 |
---|---|
N | 在多行模式空间的命令,表示匹配到的内容及下一行 |
D | 在多行模式空间的命令,删除模式空间中的第一行 |
h或H | 将模式空间的内容复制或追加到保持空间 |
g或G | 将保持空间的内容复制或追加到模式空间 |
x | 交换模式空间和保持空间的内容 |
N命令 : 在多行模式空间的命令,表示匹配到的内容及下一行
[root@slave ~]# cat ab
.Ah "Major Heading"
see section 1.4
see section 12.9
(see section 12.8)
[root@slave ~]# sed -n '/\.Ah/{N;p}' ab #显示匹配的这一行以及下一行
.Ah "Major Heading"
see section 1.4
[root@slave ~]# sed -n '/\.Ah/{n;p}' ab #N和n的区别,n只在模式空间中写入一行而N则是两行
see section 1.4
[root@slave ~]# sed '/\.Ah/{N;s/Heading"\nsee/Heading" see/g}' ab #把两行和并为一行
.Ah "Major Heading" see section 1.4
see section 12.9
(see section 12.8)
D命令 : 在多行模式空间的命令,表示删除模式空间中的第一行,与d不同的是d命令删除后会在模式空间中读入新的一行而D命令则是删除后不会读入新的文本
[root@slave ~]# cat a
This line is followed by 1 blank line.
This line is followed by 2 blank lines.
This line is followed by 3 blank lines.
This line is followed by 4 blank lines.
This is the end.
[root@slave ~]# sed '/^$/{N;/^\n$/D}' a #删除空行N一次读入两行文本到模式空间
This line is followed by 1 blank line.
#由于匹配到这一行时第二行不是空行所有跳过
This line is followed by 2 blank lines.
#匹配到这一行时下一行是空行所有进行处理,所以删除了一行
This line is followed by 3 blank lines.
#匹配到这里时先删除了一行后,还剩之前没匹配上的一行空行
This line is followed by 4 blank lines.
This is the end.
[root@slave ~]# sed '/^$/{N;/^\n$/d}' a
This line is followed by 1 blank line.
This line is followed by 2 blank lines.
This line is followed by 3 blank lines.
This line is followed by 4 blank lines.
This is the end.
示例1
把文件a中的1和2的行交换位置
[root@slave ~]# cat a
1
22
11
222
111
2222
//首先匹配1的行,把匹配到的内容放入保持空间;然后匹配2的行再把保持空间的内容追加到模式空间
[root@slave ~]# sed '/1/{h;d};/2/G' a
22
1
222
11
2222
111
[root@slave ~]#
示例2
替换the与statement中间单词的大小写
[root@slave ~]# cat a
find the Match statement
Consult the Get statement.
Using the Read statement to retrieve data
首先匹配包含有the .* statement的行放入保持空间然后把the .* statement替换为.*
[root@slave ~]# sed -r '/the .* statement/{h;s/.*the (.*) statement.*/\1/}' a
Match
Get
Read
然后把它们改变大小写y/abcdefghyjklmnopqrstuvwxyz/ABCDEFGHYZKLMNOPQRSTUVWXYZ/表示把匹配到的字符全部改为大写
[root@slave ~]# sed -r '/the .* statement/{h;s/.*the (.*) statement.*/\1/;y/abcdefghyjklmnopqrstuvwxyz/ABCDEFGHYZKLMNOPQRSTUVWXYZ/;}' a
MATCH
GET
READ
再然后把保持开机的内容追加回模式空间
[root@slave ~]# sed -r '/the .* statement/{h;s/.*the (.*) statement.*/\1/;y/abcdefghyjklmnopqrstuvwxyz/ABCDEFGHYZKLMNOPQRSTUVWXYZ/;G;}' a
MATCH
find the Match statement
GET
Consult the Get statement.
READ
Using the Read statement to retrieve data
最后进行排序
第一个(.*)\n表示换行前的所有字符也就是MATCH、GET、READ
第二个(.*the )表示the前面的所有字符已经后面一个空格
中间的.*是要被替换的内容
第三个( statement.*)表示statement前一个空格就statement本身和后面所有的字符
[root@slave ~]# sed -r '/the .* statement/{h;s/.*the (.*) statement.*/\1/;y/abcdefghyjklmnopqrstuvwxyz/ABCDEFGHYZKLMNOPQRSTUVWXYZ/;G;s/(.*)\n(.*the ).*( statement.*)/\2\1\3/}' a
find the MATCH statement
Consult the GET statement.
Using the READ statement to retrieve data