title: 【Linux基础】sed编辑器
id: 4
date: 2023-09-04 16:07:04
auther: zwf632123
cover: /upload/th.jpeg
excerpt: sed命令 作者:南梁客 关键字:Linux sed 更新时间:2022年3月20日 1、概述 sed 即为Stream EDiter(流编辑器),用程序的方式编辑文本,不同于vi编辑器,sed命令是非交互式处理文件方式。支持正则表达式。 使用场景如下: ①自动化脚本中,非交互式方式编辑的场合; ②
permalink: /archives/4
categories:

  • tec
    tags:
  • sed

sed命令
  • 作者:南梁客
  • 关键字:Linux sed
  • 更新时间:2022年3月20日

1、概述

sed 即为Stream EDiter(流编辑器),用程序的方式编辑文本,不同于vi编辑器,sed命令是非交互式处理文件方式。支持正则表达式

使用场景如下:

  • ①自动化脚本中,非交互式方式编辑的场合;
  • ②大批量重复性的编辑需求;
  • ③复杂的编辑命令,在交互式编辑过程中难以输入。

2、原理

  • sed从指定的文件中读取内容,每次只读取一行数据,且把读到的数据存储在临时缓冲区中,该缓冲区称为模式空间(pattern space);模式空间最多保存8192字节,对行的处理过程就在模式空间中进行;

  • sed还有一个临时空间,称为保留空间(hold space)[按照通常应用,模式空间和保留空间配合可以实现剪切功能]

  • sed将处理后的文件

  • 之后sed命令处理模式空间中的内容;

  • 把处理模式空间内容后的结果打印到标准输出中;

  • 接着处理下一行内容。
    重复以上步骤,直到处理完最后一行为止。
    说明: 默认情况下,在处理过程中,文件中的内容不会发生变化。如果想对处理后的结果同步到源文件中,需要使用-i选项。

3、格式

sed  [options] "commands" [file]

例:

sed -n '1,4s/root/ROOT/p' test.txt

-n: 为sed选项

1,4s/root/ROOT/p表示commands

1,4表示address

s表示替换command

p表示替换打印flag(flag只存在于替换,其他处理过程中没有)

3.1 选项说明

image-20220216173253299

3.1.1 常用选项

(1)-n/--quiet/--silent

-n: 使用静默模式(silent)。默认情况下,所有读取到的数据都会被输出到STFOUT中,静默模式只会显示经过sed处理后的数据。

sed '1,2l' sedtest
sed -n '1,2l' sedtest

image-20220107222324050

(2)-e script或--expression=script

-e: 如果一次sed需要进行多种操作,则需要使用-e来指定多条命令,一个-e后面加一个操作。

sed -n -e '1,2l' '6,7l' sedtest    #错误命令
sed -n -e '1,2l' -e '6,7l' sedtest 
sed -n --expression='1,2l' --expression='6,7l' sedtest	#使用长选项

image-20220110205916857

说明: 如果在 ‘ ’ 中多个命令之间使用“;”也可以有相同的效果。

以上示例也可以用以下命令实现:

sed -n -e '1,2l; 6,7l' sedtest

image-20220119172918285

(3)-f script-file或--file=script-file

-f:将sed的动作写在文件中,-f $file可以执行$file中指定的动作。

sed -n -f sed-f-test sedtest
sed -n --file=sed-f-test sedtest			#长选项使用方法

image-20220110214325803

(4)-r或--regexp-extended

-r: 默认情况下,sed命令支持基础正则表达式,使用-r选项来指定使用扩展表达式。

sed -n '/libs\+/p' sedtest				#使用基本正则表达式匹配
sed -n '/libs+/p' sedtest				#不加-r选项,用扩展正则表达式匹配
sed -nr '/libs+/p' sedtest				#加-r选项,用扩展正则表达式匹配

image-20220111185752125

说明: shell中基本正则表达式 \+ 和扩展正则表达式的 + 的效果相同。

(5)-i[SUFFIX]或--in-place[=SUFFIX]

-i: 直接修改源文件的内容及备份源文件

默认情况下,不加 -i 选项,sed处理的文本不会修改源文件。如果需要对源文件进行修改操作,可以使用-i选项。

sed -n '1,3p' sedtest			#不修改源文件的处理
sed -n -i '1,3p' sedtest		#修改源文件的处理

image-20220111190945994

同时,使用-i选项可以指定在修改源文件的同时备份源文件。

sed -n -i_bak$(date +%Y%m%d) '2,5p' sedtest		#修改源文件的同时备份源文件

image-20220111195723625

3.1.2 非常用选项

--follow-symlinks:当输入的文件为配置文件时,可能包含软连接,对软连接的编辑可能会导致文件失效。加入--follow-symlinks 后,sed 会识别这些软连接,并选择性地不进行修改。(未测试

(2)-c或--copy

-c:在含有-i[suffix]模式下,如果-i后面填写了后缀名,如果有-c选项,那么-i[suffix]指定的备份所有者将会改变成当前用户,修改后的原文件所有者不改变,如果没有-c选项,原文件改变后所有者变为当前用户,备份文件所有者不改变,也就是原来文件的所有者。

useradd mytest										#创建用户
chown mytest:mytest sedtest							#修改文件属主
sed -n -i_bak$(date +%Y%m%d) '2,5p' sedtest			#不加-c,-i备份文件时不修改属主
sed -n -c -i_bak-c$(date +%Y%m%d) '2,5p' sedtest 	#加-c,-i备份文件时修改属主

image-20220111202829542

(3)-b或--binary

-b:以二进制模式打开文件(暂无经典测试案例

(4)-l N或--line-length=N

-l N:指定每行输出长度N。如果后面的command中如果有l(是英文L的小写),就可以通过这里的-l选项来指定每一行的显示长度,默认是70个字符,如果超过,将会通过跳脱字符“\”来换行,包括转义字符,但必须要与后面的 –e 指定的指令 l 一起用。

sed -l 55 '1,3p' sedtest			#使用-l选项,但不适用l动作,-l没有效果
sed -l 55 '1,3l' sedtest			#使用-l选项,并使用l动作,格式化每行的输出长度

image-20220111212933184

(5)--posix

--posix:禁用所有GNU扩展。

sed -n -r '/libs+/p' sedtest					#使用扩展正则表达式匹配
sed -n -r --posix '/libs+/p' sedtest			#允许扩展正则表达式,但禁止所有GNU扩展
sed -n --posix '/libs\+/p' sedtest				#使用基本正则表达式,但禁止所有GNU扩展
sed -n '/libs\+/p' sedtest						#使用基本正则表达式

image-20220111213545615

说明: 通过上述测试发现,在使用--posix时,基本正则表达式匹配也不生效。

(6)-s或--separate

-s:将输入的文件视为需要进行分别处理的单独文件,而不是把它们视为一整体的长输入,多用于处理多个文本的文件处理。

sed -n '1,5p' *test					#只处理第一个以test结尾的文件
sed -n -s '1,5p' *test				#处理所有以test结尾的文件

image-20220111221448137

(7)-u或--unbuffered

-u:从输入文件读取最少的数据,更频繁的刷新输出。(暂无经典测试案例

个人理解: 在对时时更新的数据进行处理时,sed会将数据读取到缓冲区,为了时时能够刷新处理结果,利用该选项可以提高读取到缓冲区的频率,进行随时更新。

(8)-z或--null-data

-z:将行分隔符由换行符(回车)替换成NULL值。(暂无经典测试案例

3.2 command

严格来说,这一部分是address+command+flag

3.2.1 address

address的作用是指定要处理的文本范围。

(1)指定起始和结束位置

StartLine,EndLine

表示指定起始行(StartLine)和结束行(EndLine

例:打印sedpasswd文件的第3行到第10行。

nl sedpasswd|sed -n '3,10p'

说明: 为了方便查看,利用nl命令给文件添加行号。

image-20220118214828487

$表示最后表示最后一行。注意在定位起始行的时候,$是最后一行,不是正则中的以某个字符结尾。

(2)指定某一行

LineNumber

表示对指定的某一行进行处理。

例1:打印sedpasswd文件中的第7行。

nl sedpasswd|sed -n '7 p'

说明: 7和p之间可以有没有空格,效果一样。

image-20220119161426494

例2:替换sedpasswd文件第9行中的“:”为“#”。

image-20220119161821872

(3)指定起始行和偏移量

StartLine +N

表示处理从StartLine行开始到之后N行的内容。

说明: 其中包括StartLine。

例1:打印sedpasswd文件第3行及之后5行的内容。

nl sedpasswd|sed -n '3,+5 p'

image-20220119162553953

例2:替换第4行及后面3行中sbin为SBIN。

nl sedpasswd|sed '4,+3 s/sbin/SBIN/g'

image-20220119163135895

(4)使用正则表达式定位行

/RegExp

表示用正则表达式匹配待处理的行。

例:打印sedpasswd文件中以nologin结尾的行。

nl sedpasswd|sed -n '/nologin$/p'

image-20220118221136366

(5)通过正则表达式定位范围

/RegExp1/,/RegExp2/

表示处理第一次匹配到RegExp1至第一次匹配到RegExp2的行。

说明: 匹配模式要用 //,并且两个匹配模式之间用 隔开。

例1:打印sedpasswd文件中ftp第一次出现的行至第一次匹配到以bash结尾的行。

nl sedpasswd|sed -n '/ftp/,/bash$/p'

image-20220118222152735

例2:替换sedpasswd文件中nobody第一次出现的行至sshd第一次出现的行中sshd为SSHD。

sed  '/nobody/,/sshd/ s/bin/BIN/g' sedpasswd

image-20220119155437866

(6)混合定址

通过位置定址和正则定址定位待处理的行。

将上述几种定址方式结合使用,来定位需要处理的文本。

例1:打印sedpasswd文件中第3行开始至第1次匹配到bin(只有bin这个字符)的行。

nl sedpasswd|sed -n '3,/\<bin\>/p'

说明:\<bin\>是运用正则表达式匹配整词的方法。

image-20220119171231059

(7)步长匹配

~: 符号可以实现用数字定址时的步长指定,不指定时默认为1。

例:打印sedpasswd文件中1,4,7,10,......的行。

nl sedpasswd|sed -n '1~3p'

image-20220216092859720

3.2.2 command(动作)

image-20220216172019833

说明: 可以通过通过定址方式先对需要处理的行进行定位,再通过command做相应的处理。如果不进行定址,默认处理的是所有文本内容。

常用command解释如下。

(1)a\ 当前行下方添加字符

a: 新增,表示a后面可以接字符串,字符串会在下一行被新增。

例:在sedpasswd文件中有bash的行的下一行添加“#that user bash is /bin/bash”

sed '/bash/ a\#that user bash is /bin/bash' sedpasswd

image-20220119175837649

(2)i\ 在当前行上方添加字符

i: 新增,表示a后面可以接字符串,字符串会在上一行被新增。

例:在sedpasswd文件中第3行到第7行之间的行前面添加“#this user is base”。

nl sedpasswd |sed '3,7 i/#this user is base'

image-20220120100727975

(3)c\ 用新的文本替换选定的行

c: 替换,表示a后面可以接字符串,字符串会替换选定的行。

例:将sedpasswd中有sbin的行替换成“#This user is important”

nl sedpasswd |sed '/root/ c\#This user is important'

image-20220120213537747

(4)d 删除选定的行

d: 删除,表示删除选择的行

例:将sedpasswd中有var的行删除

sed  '/var/d' sedpasswd

image-20220207155358199

(5)s 替换指定字符

s: 替换,表示替换指定的行中匹配到的行。

例:替换sedpasswd文件中前5行中的var为VAR

nl sedpasswd |sed '1,+5s/var/VAR/'

image-20220207162328893

(5)p 打印模板块的行

p: 打印模式空间中的行。

例:打印sedpasswd文件中第3到第7行。

nl sedpasswd |sed -n '3,7p'

image-20220207163552591

(6)w 将匹配到的行追加到指定文件的末尾

w file:将匹配到的行追加到$file文件中

例:将sshtest文件中以Accept开头的行写入到sshback文件中

sed -n '/^Accept/w sshback' sshtest

image-20220207165542702

(7) r 将指定文件中的内容添加到匹配到的行处

r file:将file文件中的内容添加到匹配到的行处

例:将sshback文件的内容追加到sedpasswd文件的第2行之后

nl sedpasswd |sed '3r sshback'

image-20220207170219269

(8) ! 没有被指定匹配信息匹配到的行

!:表示取反,即没有被匹配到的行

例:匹配sedpasswd文件中没有root的行

nl sedpasswd|sed -n '/root/!p'

image-20220207173318518

(9)= 打印匹配内容的行号

=: 以单独行的形式打印匹配内容的行号

例:打印sedpasswd文件中有root的行号

sed  '/root/=' sedpasswd		#显示所有行,只打印匹配行的行号
sed  -n '/root/=' sedpasswd		#只打印匹配行的行号

image-20220207173847894

3.2.3 替换flag

image-20220211111637844

说明: 替换标记是在替换处理时使用。

(1)指定替换位置

不加任何flag,替换只会将每一行匹配到的值的第一个字符做对应替换,通过指定位置可以替换指定位置上的字符。

例:将sedpasswd文件中有shutdown的行的第2个shutdown字符串替换成SHUTDOWN。

nl sedpasswd |sed '/shutdown/s/shutdown/SHUTDOWN/2'

image-20220211113120113

(1)i 忽略匹配值的大小写

i:表示在替换时,忽略匹配项的大小写

例:将sedpasswd文件中的ssh(无论大小写),都替换为sshm。

nl sedpasswd |sed  's/ssh/sshm/gi'

image-20220211112414800

(2)g 行内全面替换

g:表示替换每一行所有匹配到的字符为新字符

说明:

  • 默认情况下,替换只替换第一个被匹配到的内容

  • g前面可以加正整数N表示将第N个到最后一个匹配到的字符进行替换

例1:替换sedpasswd文件中每一行第一个bin字符为BIN(默认替换)

nl sedpasswd |sed 's/bin/BIN/'

image-20220209162102376

例2:替换sedpasswd文件中所有bin为VAR。

nl sedpasswd |sed 's/bin/BIN/g'

image-20220209164422617

例3:替换sedpasswd文件中每一行中第2个到最后一个bin为VAR

nl sedpasswd |sed 's/bin/BIN/2g'

image-20220209165254836

(3)p 打印匹配到的行

p:表示打印待替换的行,替换命令默认有打印标识。通过以下示例可知,加p和不加p都是会打印结果,但是加p之后需要再加n选项。

nl sedpasswd |sed -n 's/bin/BIN/p'
nl sedpasswd |sed -n 's/bin/BIN/gp'

image-20220209170836451

(4)w 表示把替换后的行写入到其他文件中

w:表示将替换处理后的行写入到新的文件中

例:替换sedpasswd文件中第3行到第10行中的:为|,并将处理结果输出到newfile文件中

nl sedpasswd|sed '3,10s/:/|/gw newfile'

image-20220209174508345

(5)y 把一个字符翻译为另外的字符(但是不用于正则表达式)

y:表示把一个字符替换为指定的字符,但不能使用正则表达式

说明:

​ 不同于s替换,s会将匹配到的所有字符替换为目标字符,相当于把一个整体替换为另一个整体,而y可以看作是一个字符替换为对应的另一个字符;

​ y转换时,待转换的字符个数和目标字符个数要相同,因为要一一对应。

image-20220210114839270

例1:将sedpassed文件中第2到第6行中的abc字母替换成XYZ。

nl sedpasswd|sed '2,6y/abc/XYZ/'

image-20220210151149155

例2:将sedpasswd文件中有root的行都转换为大写字母。

nl sedpasswd |sed '/root/y/abcdefghijklmnopqrstuvwxyz/ABCDEFGHIJKLMNOPQRSTUVWXYZ/'

image-20220210152334031

(6)/N(N为正整数) 引用子串匹配

\N:配合正则表达式的字串匹配使用,将字串匹配进行后向引用。

作用: 通常情况用于在某个字符前面或后面或前后新增或删除字符和变换多个匹配项的位置

例1:将sshtest文件中“Accept+其他字符”的字符转换成“Accept:”。

sed -n 's/\(Accept\)\w\+/\1:/p' sshtest			#正则表达式匹配
sed -rn 's/(Accept)\w+/\1:/p' sshtest			#扩展正则表达式

\( \)是正则中的分组,\w\+是正则中任意字母数字,\1表示后向引用前面的第一个分组;

在扩展正则表达式中分组用(),任意字母数字用\w+表示。

image-20220211101137603

例2:将sshtest文件中的“Accept+其他字符”和“LC+其他字符“的位置进行替换。

nl sshtest|sed -n 's/\(Accept\w\+\) \(LC\w\+\)/\2 \1/p'		#正则匹配
nl sshtest|sed -rn 's/(Accept\w+) (LC\w+)/\2 \1/p'			#扩展正则匹配

image-20220211104538845

(7)& 已匹配字符

&:表示已经匹配到的字符

作用: 对前面匹配到的字符做引用,进行字符前后新增字符。

例:将sedpasswd文件中所有的root字符串用“|”隔开。

nl sedpasswd | sed 's/root/|&|/g'

3.3 特殊说明

3.3.1 定界符

​ 对于上面替换命令的示例,出于个人习惯使用的定界符是“/”,而定界符可以用任意三个相同字符,用可以是相同的三个字母、数字、特殊字符。

​ 以下示例三个替换命令是一样的。

例:替换sedpasswd文件中有root的行中的“:”字符为“#”。

 nl sedpasswd |sed '/root/s/:/#/g'|grep root			#/为定界符
 nl sedpasswd |sed '/root/s@:@#@g'|grep root			#@为定界符
 nl sedpasswd |sed '/root/s2:2#2g'|grep root			#2为定界符
 nl sedpasswd |sed '/root/sh:h#hg'|grep root			#h为定界符

image-20220211160912866

注意: 对于匹配项或替换项中有定界符时,需要转义,或者用其他定界符。

image-20220211161412331

3.3.2 命令组合使用

​ 通常情况下,对于命令处理后的结果可以给下一个命令处理,可以使用管道符|,在sed命令中,处理多个命令的方法有如下三种,且三种命令都是等效的。

  • 利用管道
sed ‘command1’|sed 'command2'
  • 使用“;”
sed 'command1;command2' 
  • -e选项
sed -e 'command1' -e 'command2'

3.3.3 命令分组

​ 在有多个条件进行执行命令时,可以通过命令分组使用。

​ 如果使用正则进行定址且进行替换时,可以将替换的command用{command}表示。

例:将sedpasswd文件中有root的行中的“:”替换成”|“。

nl sedpasswd|sed '/root/s/:/|/g'
nl sedpasswd|sed '/root/{s/:/|/g}'     #两个命令等效

image-20220211113807238

多个flag可以组合使用。

例:将sedpasswd文件中有nologin的行中的第3个到最后的":"替换成”$“且保存到sednologin文件中。

nl sedpasswd |sed "/nologin/s/:/$/2gw sednologin"

image-20220211115054815

​ 多个条件同时使用是,可以嵌套使用,嵌套的命令分组可以用{}分开。

例:将sedpassed文件中第9行到最后一行中有var的行删除,且将“/”替换成@。

nl sedpasswd|sed '9,${/var/d;s/:/@/g}'

image-20220212120458310

3.3.4 不常用command

(1)x 模式空间和保留空间互换

x:表示模式空间和保留空间互换

说明: x通常用于删除某一行且保留行的位置为空白行;

​ x其他用法需要配合别的命令实现特定的功能。

例:将第2到第5行进行模式空间和保留空间进行互换。

nl sedpasswd|sed '2,5x'

image-20220211174223853

说明: 关于第2行后面有一个空格和第2行缺失的说明。

​ 首先,每读到一行,保留空间中就会变更一个空行+该行的模式,之后相当于保留空间进行合并,最

后将模式空间和保留空间进行互换,互换之后就会出现第一个被处理的行时空白行,最后一个被处理的

行超出处理空间。

​ 读取第一个匹配行,此时,保留空间为空,保留空间和模式空间互换,得到模式空间为空行,输出

为空行;读取第二个匹配行,这时因为第一行处理时模式空间和保留空间做了互换,因此,保留空间中

的内容为第一个匹配行,交换当前模式空间和保留空间之后,输出为第一个匹配行;以此类推,当处理

第n个匹配行时,保留空间中的内容为第n-1个匹配行,所以输出为第n-1个匹配项。类似于下图:

image-20220213165520514

​ 通过命令可以确认结果:

​ 不做交换时模式空间如下:

image-20220212105557165

​ 交换后的模式空间如下:

image-20220212105925683

​ 最后的结果中就有了第2行为空白行,第5行缺失。

​ 这种方式通常用于删除某一行,且保留该行的位置为空白行。

例:删除sedpasswd文件中的第7行。

nl sedpasswd|sed '7x'

image-20220212121720936

(2)g,G,h,H

g:将保留空间中的内容复制到模式空间,覆盖模式空间中原来的值,不保留模式空间中原来的数据;

G:将保留空间中的内容追加到模式空间,保留模式空间中的数据;

h:将模式空间中的内容复制到保留空间,覆盖保留空间中原来的值,不保留保留空间中原来的数据;

H:将模式空间中的内容追加到保留空间,保留模式空间中的数据。

通常g、G、h、H、x配合使用。

  • 测试g:

g可以将保留空间中的内容复制到模式空间中。

nl gGhH |sed '2,3g'

说明: 因为默认情况下,保留空间中是空值,所以,将当前保留空间中的行(空值)复制到gGhH文件

中的第2和第3行,则输出这两行为空行。

image-20220213180407001

nl gGhH |sed '3,5g;x'

image-20220214105557486

命令流程:

image-20220214105807291

  • 测试G

G可以将保留空间中的内容追加到模式空间中。

说明: 因为默认情况下,保留空间中是空值,所以,将当前保留空间中的行(空值)追加到gGhH文件中时,相当于在所有行下面添加空白行。

nl gGhH |sed 'G'

image-20220214110926969

nl gGhH |sed 'G;x'

image-20220214111357595

命令处理流程:

image-20220214114419224

nl gGhH |sed '2x;3G'

剪切第2行到第3行之后,并保留第2行的位置为空行。

image-20220214114558717

命令处理流程:

image-20220215091114979

  • 测试h

h可以将模式空间中的内容复制到保留空间。

说明: 保留空间中的内容不能直接输出出来,配合模式空间输出。

sed 'G;h' gGhH

image-20220215095210699

命令处理流程:

image-20220215101723544

 sed '2h;4G' gGhH

​ 将第2行复制到第4行后面。

image-20220215102837285

命令处理流程:
image-20220215103827513

  • 测试H

H可以将模式空间中的内容追加到保留空间中。

sed 'x;H' gGhH

image-20220215105101455

命令处理流程:

image-20220215110802286

附加处理示例

  • 1 复制

例:复制gGhH文件第2行到第5行的内容到第3行后面。

sed '2h;3,5H;3G' gGhH

image-20220215111908934

说明: 复制n-m行的内容到p行后面的命令为:

sed 'nh;(n+1),mH;pH' $file

nh作用是覆盖保留空间中的空白行;

  • 2 剪切

​ 例:剪切gGhH文件第2行到第5行内容到第6行后面。

sed '2h;3,5H;2,5d;6G' gGhH

说明: 2h为了覆盖保留空间中的空白行;

​ 2,5d删除模式空间中的数据;

​ G前面的数字不能在剪切行的范围。

  • 3 添加空白行

​ 在指定行的前面新增一个空白行。

​ 例1:在gGhH文件第3行到第5行前面新增一个空白行。

sed  '3,5{x;p;x}' gGhH

image-20220215114106255

​ 例2:在gGhH文件第2行到第6行后面新增一个空白行。

sed  '2,6G' gGhH
sed  '2,6{x;H;x}' gGhH

image-20220215114437106

  • 3 在gGhH文件第3行到最后一行前后各加一个空白行
sed  '2,${x;p;x;G}' gGhH

image-20220215115003376

  • 4 新增多个空白行

​ 添加多个空白行的方法就是重复添加一行的command。

image-20220215115331065

image-20220215115449186

(3)n 读取本行,处理本行的下一行

n:读取本行的内容,处理下一行,不处理本行。

说明: n是读取匹配到行的下一行不在匹配行之列,则读取匹配到的第一行,处理第一行所在行的下一行;之后读取第二行,再处理第二行所在行的下一行,以此类推;如果n匹配到的行的下一行也是在匹配行的范围之内,则读取匹配行的第一行,处理第一行的下一行(也是下一个匹配行);之后读取第三个匹配行,处理第二个匹配行的下一行。

​ 处理过程可以理解为:

image-20220215154906734

通过打印(p)就能看出n的作用。

nl sedpasswd|sed 'n;p'

image-20220215145216461

​ 上例中所有偶数行都在匹配行之列,所以每次处理时都会跳过偶数行。

image-20220215150459493

(4)N 将下一行追加到匹配行后

​ 将匹配行的下一行追加到匹配行的后面,在模式空间中将匹配行和下一行视为一行处理,匹配行和下一行中间有一个换行符\n。

​ 处理过程理解为:

image-20220215163525213

​ 例:通过打印(p)验证N的功能。

image-20220215155818489

image-20220215160002488

(5)P 打印模式空间中第一个换行符\n前的内容

说明: 该打印方式是N处理后的行的处理,因为在N处理后在模式空间中会有\n。

image-20220215162526622

(6)D 删除模式空间中第一个换行符\n前的内容

说明: 删除N处理后第一个换行符\n之前的内容。

image-20220215162916995

​ N;P的处理流程如下:

image-20220215164216013

匹配到最后一行时,没有相应的下一行,处理流程结束,此时输出就为最后在模式空间中的内容。

(7)W 将模式空间中第一个换行符\n之前的行写入到指定文件

说明: N处理后第一个换行符\n之前的内容。

image-20220215165242886

4、常用案例

(1)行首加字符

​ 注释sedpasswd文件中有var的行(即在行首添加#)。

image-20220216094758210

(2)行尾加字符

​ 在sedpasswd文件中,所有有root的行后面添加注释信息“ #This is root user.”

sed '/root/s/$/ #This is root user./' sedpasswd

image-20220216095238273

(3)匹配偶数行

  • 步长匹配方式
nl sedpasswd|sed -n '2~2p'

image-20220216095902721

  • n;p或n;P命令方式
nl sedpasswd|sed -n 'n;p'
nl sedpasswd|sed -n 'n;P'

image-20220216100012251

  • n;d方式
nl sedpasswd|sed '1!n;d'

image-20220216100842570

(4)匹配奇数行

  • 步长匹配方式
nl sedpasswd|sed -n '1~2p'

image-20220216103411473

  • p;n或p;N或P;n或P;N方式
nl sedpasswd|sed -n 'P;N'
nl sedpasswd|sed -n 'P;n'
nl sedpasswd|sed -n 'p;n'
nl sedpasswd|sed -n 'P;N'

image-20220216103752078

说明: N;P方式也可以匹配奇数行,但是,如果文件中的总行数是奇数个,则最后一个奇数行是匹配不到的。

nl sedpasswd|sed -n 'N;P'

image-20220216104230544

  • n;d方式
nl sedpasswd|sed 'n;d'

image-20220216104427559

(5)删除空白行

sed '2,9G;w sedblock' sedpasswd			#创建一个2,9行后面有空行的文件sedblock
sed '/^$/d' sedblock

image-20220216110001077

(6)奇数行和偶数行合并

​ 奇数行和偶数行合并,且用一个空格分开

sed 'N;s/\n/ /g' sedpasswd

image-20220216113144143

(7)设置在行首显示行号

说明: 使用“=”可以在匹配行的上面插入一个之后行号的行,利用N可以将行号设置到行首。

sed  '=' sedpasswd |sed 'N;s/\n/ /g'

image-20220216114742385

注意: 从这个例子可以看出,管道命令和-e及";"还是有一定的区别,不是所有情境下三者都等效。

image-20220216115347250

(8)删除指定字符

​例:删除sshtest文件中有“LC”的行中第4个字符。

​为了书写简便,这里用

sed -r  '/LC/s/(.{3})(.)(.*)$/\1\3/' sshtest			#通用方法
sed -r  '/LC/s/(\w{3})(.)(.*)$/\1\3/' sshtest			#如果没有特殊字符可以这样使用

image-20220216153216156

(9)字符(串)交换

​例1:将sshtest文件中有yes的行的第3个字符和第5个字符交换。

sed -r '/yes/s/(.)(.)(.{2})(.)(.*)$/\1\4\3\2\5/' sshtest

image-20220216160019258

命令解释:

第一个(.)匹配这一行的第一个字符;

第二个(.)匹配这一行的第二个字符;

(.{2})匹配第3和第4个字符;

第三个(.)匹配第5个字符;

(.*)$表示匹配第6个字符到结尾;

最后通过交换第2个分组和第4个分组即可完成行中第2个字符和第5个字符之间的交换。

​ 例2:将sshtest文件中有no的行的第3-6个字符串和第9-10个字符串交换。

sed -r '/no/s/(.{2})(.{4})(.{2})(.{2})(.*)$/\1\4\3\2\5/' sshtest

image-20220216161427183

(10)修改配置文件

​ 例:修改selinux_config文件中“SELINUX”的值为disabled

sed -r 's/(SELINUX=).*/\1disabled/' selinux_config

image-20220216162506540

(11)删除行首的空格

​ 例1:删除selinux_space文件中所有行首的所有空行。

sed  's/^\( \+\)//g' selinux_space
sed  -r 's/^( +)//g' selinux_space

sed 's/^[ \t]*//g' selinux_space
sed 's/^[[:space:]]*//g' selinux_space

image-20220216164434152