Linux三剑客之sed

1、sed 是什么
sed是stream editor的简称,也就是流编辑器。它一次处理一行内容,处理时,把当前处理的行存储在临时缓冲区中,称为“模式空间”(pattern space),接着用sed命令处理缓冲区中的内容,处理完成后,把缓冲区的内容送往屏幕。接着处理下一行,这样不断重复,直到文件末尾。文件内容并没有 改变,除非你使用重定向存储输出。

sed 是一个流编辑器(stream editor),主要用来执行文本替换。 sed 主要设计的目的是以批处理的方式而不是以交互的方式来编辑文件。

sed 是一种新型的,非交互式的编辑器。它能执行与编辑器 vi 和 ex 相同的编辑任务。sed 编辑器没有提供交互式使用方式,使用者只能在命令行输入编辑命令、指定文件名,然后在屏幕上查看输出。 sed 编辑器没有破坏性,它不会修改文件,除非使用 shell 重定向来保存输出结果。默认情况下,所有的输出行都被打印到屏幕上。

2、sed工作原理

 sed会一次处理一行内容。处理时,把当前处理的行存储在临时缓冲区中,成为"模式空间",接着用sed命令处理缓冲区中的内容,处理完成后,把缓冲区的内容送往屏幕。接着处理下一行,这样不断重复,直到文件末尾。文件内容并没有改变,除非你使用重定向存储输出。

3、正则表达式概念

在编写处理字符串的程序或网页时,经常会有查找符合某些复杂规则的字符串的需要。正则表达式就是用于描述这些规则的工具,换句话说,正则表达式就是记录文本规则的代码。许多程序设计语言都支持利用正则表达式进行字符串操作。在很多文本编辑器里,正则表达式通常被用来检索、替换那些符合某个模式的文本。

4、sed 语法

sed 命令行格式为: sed  [选项]  'command'  输入文本

1)sed 定位
Sed 命令在没有给定的位置时,默认会处理所有行

Sed 支持一下几种地址类型:

 first~step

这两个单词的意思: first 指起始匹配行, step 指步长,例如: sed -n 2~5p 含义:从第二行开始匹配,隔 5 行匹配一次,即 2,7,12.......。

 $

这个$符表示匹配最后一行。

 /REGEXP/

这个是表示匹配正则那一行,通过//之间的正则来匹配。

 \cREGEXPc

这个是表示匹配正则那一行,通过\c 和 c 之间的正则来匹配,c 可以是任一字符

 addr1, add2定址 addr1, add2 决定用于对哪些行进行编辑。地址的形式可以是数字、正则表达式或二者的结合。如果没有指定地址, sed 将处理输入文件中的所有行。如果定址是一个数字,则这个数字代表行号,如果是逗号分隔的两个行号,那么需要处理的定址就是两行之间的范围(包括两行在内)。范围可以是数字,正则或二者组合。

 addr1, +N

从 addr1 这行到往下 N 行匹配,总共匹配 N+1 行

addr1, ~N

将匹配addr1和addr1之后的行,直到输入行号是N的倍数的下一行

2)sed 命令常用选项

3)sed 操作命令

sed 操作命令告诉 sed 如何处理由地址指定的各输入行。如果没有指定地址, sed 就会处理输入的所有的行。

a\               在当前行后添加一行或多行

c\               用新文本修改(替换)当前行中的文本

d               删除行

i\                在当前行之前插入文本

h                把模式空间里的内容复制到暂存缓存区

H                把模式空间里的内容追加到暂存缓存区

g                取出暂存缓冲区里的内容,将其复制到模式空间,覆盖该处原有内容

G                取出暂存缓冲区里的内容,将其复制到模式空间,追加在原有内容后面

l                列出非打印字符

p               打印行

n                读入下一输入行,并从下一条命令而不是第一条命令开始处理

q                结束或退出 sed

r                从文件中读取输入行

!                对所选行以外的所有行应用命令

s                用一个字符串替换另一个

4)替换标志

g                在行内进行全局替换

p                打印行

w                将行写入文件

x                交换暂存缓冲区与模式空间的内容

y                将字符转换为另一字符(不能对正则表达式使用 y 命令)

5)报错信息与退出信息

遇到语法错误时, sed 会向标准错误输出发送一条相当简单的报错信息。但是,如果 sed判断不出错在何处,它会“断章取义”,给出令人迷惑的报错信息。如果没有语法错误, sed将会返回给 shell 一个退出状态,状态为 0 代表成功,为非 0 整数代表失败。

5、sed 使用案例

[root@shell ~]#

[root@shell ~]# touch  test.txt             #建立测试文件

[root@shell ~]# vi  test.txt                    #编辑测试文件

[root@shell ~]# cat  test.txt                #查看测试文件中的内容

1)打印命令 p

命令 p 是打印命令,用于显示模式缓存区的内容。默认情况下, sed 把输入行打印在屏幕上,选项-n 用于取消默认打印操纵。当选项-n 和命令 p 同时出现时, sed 可打印选定的内容

例1:

[root@shell ~]#

[root@shell ~]# sed  '/north/p'  test.txt

说明:默认情况下, sed 把所有输入行都打印在标准输出上。如果在某一行匹配到 north, sed就把该行另外打印一遍。 

例2:

[root@shell ~]#

[root@shell ~]# sed  -n  '/north/p'  test.txt

说明:默认情况下, sed 打印当前缓存区中的输入行。命令 p 指示 sed 将再次打印该行。选项-n 取消 sed 取消默认打印操作。选线-n 和命令配合使用,模式缓冲区内的输入行,只被打印一次。如果不指定-n 选项, sed 就会像上例中那样,打印出重复的行。如果指定了-n,则sed 只打印包含模式 north 的行

2)删除命令 d

命令 d 用于删除输入行。sed 先将输入行从文件复制到模式缓存区,然后对该行执行 sed命令,最后将模式缓存区的内容显示在屏幕上。如果发出的是命令 d,当前模式缓存区的输入行会被删除,不被显示。

例3:

[root@shell ~]#

[root@shell ~]# sed  '3d'  test.txt

说明:仅删除第 3 行,默认情况下,其余的行都被打印到屏幕上。

例4:

[root@shell ~]#

[root@shell ~]# sed  '3,$d'  test.txt

说明:删除从第三行到最后一行的内容,剩余各行被打印。地址范围是开始第 3 行,结束最后一行。

例5:

[root@shell ~]#

[root@shell ~]# sed  '/north/d'  test.txt

说明:所有包含模式 north 的行都被动删除,其余行被打印。

3)替换命令 s

命令 s 是替换命令。替换和取代文件中的文本可以通过 sed 中的 s 来实现, s 后包含在斜杠中的文本是正则表达式,后面跟着的是需要替换的文本。可以通过 g 标志对行进行全局替换

例6:

[root@shell ~]#

[root@shell ~]# sed  's/west/north/g'  test.txt

说明:s 命令用于替换。命令末端的 g 表示在行内全局替换;也就是说如果每一行里出现多个west,所有的 west 都会被替换为 north。如果没有 g 命令,则只将每一行的第一 west 替换为 north。

例7:用sed命令关闭selinux

[root@shell ~]#

[root@shell ~]# cat  /etc/selinux/config

[root@shell ~]# sed  -i  's/SELINUX=enforcing/SELINUX=disabled/g'  /etc/selinux/config

[root@shell ~]# cat  /etc/selinux/config

例8:

[root@shell ~]#

[root@shell ~]# sed  -n  's/^west/north/p'  test.txt

说明:s 命令用于替换。选线-n 与命令行末尾的标志 p 结合,告诉 sed 只打印发生替换的那些行;也就是说,如果只有在行首找到 west 并替换成 north 时才会打印此行。

例9:

[root@shell ~]#

[root@shell ~]# sed  's/[0-9][0-9]$/&.5/'  test.txt

说明:当“与”符号( &)用在替换串中时,它代表在查找串中匹配到的内容时。这个示例中所有以 2 位数结尾的行后面都被加上.5

例10:

[root@shell ~]#

[root@shell ~]# sed  -n 's/Hemenway/Jones/gp'  test.txt

说明:文件中出现的所有的 Hemenway 都被替换为 Jones,只有发生变化的行才会打印出来。选项-n 与命令 p 的组合取消了默认的输出。标志 g 的含义是表示在行内全局替换。

例11:

[root@shell ~]#

[root@shell ~]# sed  's/\(Mar\)got/\1linanne/p'  test.txt

说明:包含在圆括号里的模式 Mar 作为标签 1 保存在特定的寄存器中。替换串可以通过\1 来引用它。则 Margot 被替换为 Marlinane。

例12:

[root@shell ~]#

[root@shell ~]# sed  's#3#88#g'  test.txt

说明:紧跟在 s 命令后的字符就是查找串和替换串之间的分隔符。分隔符默认为正斜杠,但也可以改变。无论什么字符(换行符,反斜线除外),只要紧跟在 s 命令,就成了新的字符串分隔符。这个方法在查找包含正斜杠模式时很管用,例如查找路径名或生日。

4)指定行的范围:逗号

例13:

[root@shell ~]#

[root@shell ~]# sed  -n '/west/,/east/p'  test.txt

说明:打印模式 west 和 east 之间所有的行。如果 west 出现在 east 之后的某一行,则打印的范围从 west 所在行开始,到下一个出现 east 的行或文件的末尾(如果前者未出现)。图中用箭头表示出了该范围。

例14:

[root@shell ~]#

[root@shell ~]# sed  -n '5,/northeast/p'  test.txt

说明:打印从第 5 行开始 到 第一个以 northeast 开头的行之间的所有行。

例15:

[root@shell ~]#

[root@shell ~]# sed  '/west/,/east/s/$/**VACA**/'  test.txt

说明:修改从模式 west 和 east 之间的所有行,将各行的行尾($)替换为字符串**VACA**。换行符被移到新的字符串后面。

5)多重编辑命令 e

例16:

[root@shell ~]#

[root@shell ~]# sed  -e '1,3d' -e 's/Hemenway/Jones/'  test.txt

说明:选项-e 用于进行多重编辑。第一重编辑删除第 1~3 行的内容。第二重编辑将Hemenway 替换为 Jones。因为是逐行进行这两行编辑(即这两个命令都在模式空间的当前行上执行),所以编辑命令的顺序会影响结果。例如,如果两条命令都执行的是替换,前一次替换会影响后一次替换。

6)追加命令 a

a 命令是追加命令,追加将新文本到文件中当前行(即读入模式的缓存区行)的后面。不管是在命令行中,还是在 sed 脚本中, a 命令总是在斜杠的后面。

例17:

[root@shell ~]#

[root@shell ~]# sed  '/^north/a Hello world!'  test.txt

说明:命令 a 用于追加。字符串 Hello, World!被加在以 north 开头的各行之后。如果要追加的内容超过一行,则除最后一行外,其他各行都必须以反斜杠结尾。

7)插入命令 i

i 命令是插入命令,类似于 a 命令,但不是在当前行后增加文本,而是在当前行前面插入新的文本,即刚读入缓存区模式的行。

例18:

[root@shell ~]#

[root@shell ~]# sed  '/eastern/i Hello,world!\'  test.txt

说明:命令 i 是插入命令。如果在某一行匹配到模式 eastern,i 命令就在该行的上方插入命令中插入斜杠后面的文本。

8)修改命令 c

c 命令是修改命令。 sed 使用该命令将已有的文本修改成新的文本。旧文本被覆盖。

例19:

[root@shell ~]#

[root@shell ~]# sed  '/eastern/c Hello,world! \'  test.txt

说明:c 命令是修改命令。该命令将完整地修改在模式缓冲区行的当前行。如果模式 eastern被匹配, c 命令将用其后的文本去替换包含 eastern 的行

9)获取下一行命令 n

n 命令表示下一条命令。 sed 使用该命令获取输入文件的下一行,并将其读入到模式缓冲区中,任何 sed 命令都将应用到匹配行,紧接着的下一行上。

例20:

[root@shell ~]#

[root@shell ~]# sed  '/eastern/{n;s/AM/Archie/;}'  test.txt

说明:如果在某一行匹配到模式 eastern, n 命令就指示 sed 用下一个输入行(即包含 AM MainJr 的那行)替换模式空间中的当前行,并用 Archie 替换 AM,然后打印该行,再继续往下处理

10)转换命令 y

y 命令表示转换。该命令与 tr 命令相似,字符按照一对一的方式从左到右进行转换。例如 y/abc/ABC/,会把小写字母转换成大写字母, a-->A,b-->B,c-->C

例21:

[root@shell ~]#

[root@shell ~]# sed  '1,3y/abcdefghijklmnopqrstuvwxyz/ABCDEFGHIJKLMNOPQRSTUVWXYZ/' test.txt

说明:y 命令把 1~3 行中所有的小写命令字母都转换成了大写。正则表达式元字符对 y 命令不起作用。与替分隔符一样,斜杠可以被替换成其他字符。

11)退出命令 q

q 命令表示退出命令。该命令将导致 sed 程序退出,且不再进行其他的处理。

例22:

[root@shell ~]#

[root@shell ~]# sed  '5q'  test.txt

说明:打印完第 5 行之后, q 让 sed 程序退出。

例23:

[root@shell ~]#

[root@shell ~]#  sed  '/Lewis/{ s/Lewis/Joseph/;q; }'  test.txt

说明:在某行匹配到模式 Lewis 时, s 表示先用 Joseph 替换 Lewis,然后 q 命令让 sed 退出。


6、生产环境案例

在实际生产中,在修改配置文件的时候,有一些空格、空行、带“ #”开头的注释都要删除或替换,下面为大家介绍几个实用的例子

例1:

[root@shell ~]#

[root@shell ~]# touch  sed.txt

[root@shell ~]# vi  sed.txt

[root@shell ~]# cat  sed.txt                           #每行内容的前面都有空格

[root@shell ~]#

[root@shell ~]# sed  's/^[ ]*//'  sed.txt              # 注:[ ] 里面有个空格

[root@shell ~]#

[root@shell ~]# sed  's/^[[:space:]]*//' sed.txt             #等价于上面的命令,实现效果一样

例2:删除文本中空行和空格组成的行及#号注释的行

[root@shell ~]#

[root@shell ~]# grep  -Eiv "^#|^$"  /etc/ssh/ssh_config

例3:从 Google 上下载下来的配置文件往往都带有数字,现在需要删除所有行的首数字。

[root@shell ~]#

[root@shell ~]# > sed.txt

[root@shell ~]# vi  sed.txt

[root@shell ~]# cat  sed.txt

[root@shell ~]#

[root@shell ~]# sed  's/^[0-9][0-9]*//g'  sed.txt

你可能感兴趣的:(Linux三剑客之sed)