linux-shell-05 shell-脚本四剑客-sed

linux-shell-05 shell-脚本四剑客-sed

概念解析

  SED是一项Linux指令,功能同awk类似,差别在于,sed简单,对列处理的功能要差一些,awk的功能复杂,对列处理的功能比较强大。sed是一个非交互式文本编辑器,它可以对文本文件和标准输入进行编辑,标志输入可以来自键盘输入、文本重定向、字符串、变量、甚至来自于管道符。

特点:

  • sed命令利用script来处理文本文件。
  • sed可依照script的指令,来处理、编辑文本文件。
  • 逐行处理内容,一次只处理一行内容。
  • sed主要用来自动编辑一个或多个文件;简化对文件的反复操作;编写转换程序等。

语法

1
sed [-hnV] [-e<script>][-f<script文件>] [文本文件]

参数说明

1
2
3
4
5
-e<script>或--expression=<script> 以选项中指定的script来处理输入的文本文件。
-f<script文件>或--file=<script文件> 以选项中指定的script文件来处理输入的文本文件。
-h或--help 显示帮助。
-n或--quiet或--silent 仅显示script处理后的结果。
-V或--version 显示版本信息。

动作说明

1
2
3
4
5
6
- a :新增, a 的后面可以接字串,而这些字串会在新的一行出现(目前的下一行)~
- c :取代, c 的后面可以接字串,这些字串可以取代 n1,n2 之间的行!
- d :删除,因为是删除啊,所以 d 后面通常不接任何咚咚;
- i :插入, i 的后面可以接字串,而这些字串会在新的一行出现(目前的上一行);
- p :打印,亦即将某个选择的数据印出。通常 p 会与参数 sed -n 一起运行~
- s :取代,可以直接进行取代的工作哩!通常这个 s 的动作可以搭配正规表示法!例如 1,20s/old/new/g 就是啦!

sed工作流程

1、读新的一行到缓存空间(pattern space)
2、从指定的操作指令中依次取出指令执行,判断是否匹配缓存空间内容
3、如果不匹配则忽略后续的编辑命令,回到第2步继续取出下一条指令
4、如果匹配,则针对缓存的行执行后续的编辑命令;完成后,回到第2步继续取出下一条指令
5、当所有指令都应用之后,输出缓存行的内容;回到第1步继续读入下一行内容
6、当所有行都处理完之后,结束;
  sed操作的所有数据都是pattern space缓存空间内的数据,原文件并没有发生该表。如果想保留sed操作后的数据,可以使用重定向符输出到新的文件中。或者使用- i参数更改原文件。

实例解析

首先查看1.txt文件原文内容

1
2
3
4
5
6
7
8
[root@node4 ~]# cat 1.txt 
1 2 3 4 5
6 7 8 9 10
a b c d e
hello world and awk
languege php,java,python
LANGUEGE PHP,JAVA,PYTHON
[root@node4 ~]#

打印第1到5行内容

1
2
3
4
5
6
7
[root@node4 ~]# sed -n '1,5p' 1.txt 
1 2 3 4 5
6 7 8 9 10
a b c d e
hello world and awk
languege php,java,python
[root@node4 ~]#

打印文件最后一行的内容, 下面$ 代表的是最后一行

1
2
3
4
5
6
7
8
9
10
11
12
[root@node4 ~]# sed -n '$p' 1.txt 
LANGUEGE PHP,JAVA,PYTHON
[root@node4 ~]#

如果少敲了$符号,就直接打印文件全部内容
[root@node4 ~]# sed -n 'p' 1.txt
1 2 3 4 5
6 7 8 9 10
a b c d e
hello world and awk
languege php,java,python
LANGUEGE PHP,JAVA,PYTHON

然后在1.txt文件的第2行后添加一行,并将结果输出到标准输出

1
2
3
4
5
6
7
8
9
[root@node4 ~]# sed -e 2a\newline 1.txt
1 2 3 4 5
6 7 8 9 10
newline
a b c d e
hello world and awk
languege php,java,python
LANGUEGE PHP,JAVA,PYTHON
[root@node4 ~]#

再次查看文件内容,发现文件内容实际上是没有变化的。

1
2
3
4
5
6
7
8
[root@node4 ~]# cat 1.txt 
1 2 3 4 5
6 7 8 9 10
a b c d e
hello world and awk
languege php,java,python
LANGUEGE PHP,JAVA,PYTHON
[root@node4 ~]#

然后在1.txt文件的第2行后添加一行,内容为11 12 13 14 15,并将结果输出到标准输出

1
2
3
4
5
6
7
8
9
[root@node4 ~]# sed '2a 11 12 13 14 15' 1.txt 
1 2 3 4 5
6 7 8 9 10
11 12 13 14 15
a b c d e
hello world and awk
languege php,java,python
LANGUEGE PHP,JAVA,PYTHON
[root@node4 ~]#

然后在1.txt文件的第3行前面插入一行,内容为11 12 13 14 15,并将结果输出到标准输出

1
2
3
4
5
6
7
8
9
[root@node4 ~]# sed '3i 11 12 13 14 15' 1.txt
1 2 3 4 5
6 7 8 9 10
11 12 13 14 15
a b c d e
hello world and awk
languege php,java,python
LANGUEGE PHP,JAVA,PYTHON
[root@node4 ~]#

增加两行或者以上

1
2
3
4
5
6
7
8
9
10
11
12
13
[root@node4 ~]# sed '2a 11 12 13 14 15\			#这里敲\加回车可以就输入,敲'表示输入完毕
16 17 18 19 20\
21 22 23 24 25' 1.txt
1 2 3 4 5
6 7 8 9 10
11 12 13 14 15
16 17 18 19 20
21 22 23 24 25
a b c d e
hello world and awk
languege php,java,python
LANGUEGE PHP,JAVA,PYTHON
[root@node4 ~]#

在文件最后一行后追加一行:this is the last raw

1
2
3
4
5
6
7
8
9
[root@node4 ~]# sed '$a this is the last raw' 1.txt 
1 2 3 4 5
6 7 8 9 10
a b c d e
hello world and awk
languege php,java,python
LANGUEGE PHP,JAVA,PYTHON
this is the last raw
[root@node4 ~]#

以行为单位的新增/删除

将 1.txt的内容列出并且列印行号,同时,请将第 2~5 行删除!

1
2
3
4
5
6
7
8
9
10
11
[root@node4 ~]# nl 1.txt | sed '2,5d'
1 1 2 3 4 5
6 LANGUEGE PHP,JAVA,PYTHON
[root@node4 ~]# cat 1.txt
1 2 3 4 5
6 7 8 9 10
a b c d e
hello world and awk
languege php,java,python
LANGUEGE PHP,JAVA,PYTHON
[root@node4 ~]#

将 1.txt的内容列出并且列印行号,同时,请将含有java的行删除!

1
2
3
4
5
6
7
8
9
10
11
12
13
[root@node4 ~]# sed '/java/,$d' 1.txt 
1 2 3 4 5
6 7 8 9 10
a b c d e
hello world and awk
[root@node4 ~]# cat 1.txt
1 2 3 4 5
6 7 8 9 10
a b c d e
hello world and awk
languege php,java,python
LANGUEGE PHP,JAVA,PYTHON
[root@node4 ~]#

删除第 3 到最后一行

1
2
3
4
[root@node4 ~]# sed '3,$d' 1.txt 
1 2 3 4 5
6 7 8 9 10
[root@node4 ~]#

以行为单位的替换与显示

将第2-5行的内容取代成为:xxxxxxxxxx

1
2
3
4
5
[root@node4 ~]# sed '2,5c xxxxxxxxxx' 1.txt
1 2 3 4 5
xxxxxxxxxx
LANGUEGE PHP,JAVA,PYTHON
[root@node4 ~]#

数据的搜寻并替换

语法

1
sed 's/要被取代的字串/新的字串/g'

把java换成web

1
2
3
4
5
6
7
8
[root@node4 ~]# sed -e 's/java/web/g' 1.txt 
1 2 3 4 5
6 7 8 9 10
a b c d e
hello world and awk
languege php,web,python
LANGUEGE PHP,JAVA,PYTHON
[root@node4 ~]#

多点编辑

用一条sed命令完成:删除第2~4行且把java换成web

1
2
3
4
5
[root@node4 ~]# sed -e '2,4d' -e 's/java/web/g' 1.txt 
1 2 3 4 5
languege php,web,python
LANGUEGE PHP,JAVA,PYTHON
[root@node4 ~]#

直接修改文件内容(危险动作)

  sed 可以直接修改文件的内容,不必使用管道命令或数据流重导向! 不过,由于这个动作会直接修改到原始的文件,所以请你千万不要随便拿系统配置来测试! 我们还是使用文件 1.txt 文件来测试看看吧!

  在上述命令的基础上加上参数:-i,即可直接修改文件内容。

原数据

1
2
3
4
5
6
7
8
[root@node4 ~]# cat 1.txt 
1 2 3 4 5
6 7 8 9 10
a b c d e
hello world and awk
languege php,java,python
LANGUEGE PHP,JAVA,PYTHON
[root@node4 ~]#

利用 sed 直接在1.txt 最后一行加入:This is the last row

与之前我们的命令相比,只多了个:-i,于是便直接修改了文件内容。

1
2
3
4
5
6
7
8
9
10
[root@node4 ~]# sed -i '$a this is the last raw' 1.txt 
[root@node4 ~]# cat 1.txt
1 2 3 4 5
6 7 8 9 10
a b c d e
hello world and awk
languege php,java,python
LANGUEGE PHP,JAVA,PYTHON
this is the last raw
[root@node4 ~]#

常用实例

1.将本主机上的selinux设为disabled。这样修改需要重启服务器后才生效,所以要加setenforce 0 。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
[root@node4 ~]# cat /etc/selinux/config 

# This file controls the state of SELinux on the system.
# SELINUX= can take one of these three values:
# enforcing - SELinux security policy is enforced.
# permissive - SELinux prints warnings instead of enforcing.
# disabled - No SELinux policy is loaded.
SELINUX=enforcing
# SELINUXTYPE= can take one of three two values:
# targeted - Targeted processes are protected,
# minimum - Modification of targeted policy. Only selected processes are protected.
# mls - Multi Level Security protection.
SELINUXTYPE=targeted


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

# This file controls the state of SELinux on the system.
# SELINUX= can take one of these three values:
# enforcing - SELinux security policy is enforced.
# permissive - SELinux prints warnings instead of enforcing.
# disabled - No SELinux policy is loaded.
SELINUX=disabled
# SELINUXTYPE= can take one of three two values:
# targeted - Targeted processes are protected,
# minimum - Modification of targeted policy. Only selected processes are protected.
# mls - Multi Level Security protection.
SELINUXTYPE=targeted


[root@node4 ~]# getenforce
Enforcing
[root@node4 ~]# setenforce 0
[root@node4 ~]# getenforce
Permissive
[root@node4 ~]#

2.查看sshd端口号,修改它,然后改回来。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
[root@node4 ~]# sed -n '17p' /etc/ssh/sshd_config
#Port 22
[root@node4 ~]# sed -i 's/#Port 22/Port 4555/g' /etc/ssh/sshd_config
[root@node4 ~]# sed -n '17p' /etc/ssh/sshd_config
Port 4555
[root@node4 ~]# systemctl restart sshd
[root@node4 ~]# sed -i 's/Port 4555/#Port 22/g' /etc/ssh/sshd_config
[root@node4 ~]# sed -n '17p' /etc/ssh/sshd_config
#Port 22
[root@node4 ~]# systemctl restart sshd

如下,用指定内容二不是指定行来搜索并且显示出来也可以
[root@node4 ~]# sed -n '/Port/p' /etc/ssh/sshd_config
#Port 22
#GatewayPorts no
[root@node4 ~]#

sed+空行

关于空行,sed又有另外的讲究,这里我们来研究一下。

用1.txt作为测试文档

1
2
3
4
5
6
7
8
[root@node4 ~]# cat 1.txt 
1 2 3 4 5
6 7 8 9 10
a b c d e
hello world and awk
languege php,java,python
LANGUEGE PHP,JAVA,PYTHON
[root@node4 ~]#

实例解析(下列实例均直接修改文件内容)

1.在每行文本后面加一行空行

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
[root@node4 ~]# sed -i G 1.txt 
[root@node4 ~]# cat 1.txt
1 2 3 4 5

6 7 8 9 10

a b c d e

hello world and awk

languege php,java,python

LANGUEGE PHP,JAVA,PYTHON

[root@node4 ~]#

2.删除文档中所有的空行。其中”^$”表示空行。

1
2
3
4
5
6
7
8
9
[root@node4 ~]# sed -i '/^$/d' 1.txt
[root@node4 ~]# cat 1.txt
1 2 3 4 5
6 7 8 9 10
a b c d e
hello world and awk
languege php,java,python
LANGUEGE PHP,JAVA,PYTHON
[root@node4 ~]#

3.在每行文本后面加两行空行,加完记得删掉

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
[root@node4 ~]# sed -i 'G;G' 1.txt 
[root@node4 ~]# cat 1.txt
1 2 3 4 5


6 7 8 9 10


a b c d e


hello world and awk


languege php,java,python


LANGUEGE PHP,JAVA,PYTHON


[root@node4 ~]# sed -i '/^$/d' 1.txt
[root@node4 ~]# cat 1.txt
1 2 3 4 5
6 7 8 9 10
a b c d e
hello world and awk
languege php,java,python
LANGUEGE PHP,JAVA,PYTHON
[root@node4 ~]#

4.在匹配行之前加空行

1
2
3
4
5
6
7
8
9
10
[root@node4 ~]# sed -i '/a b c/ {x;p;x}' 1.txt 
[root@node4 ~]# cat 1.txt
1 2 3 4 5
6 7 8 9 10

a b c d e
hello world and awk
languege php,java,python
LANGUEGE PHP,JAVA,PYTHON
[root@node4 ~]#

5.在匹配行之后加空行

1
2
3
4
5
6
7
8
9
10
11
[root@node4 ~]# sed -i '/a b c/ G' 1.txt 
[root@node4 ~]# cat 1.txt
1 2 3 4 5
6 7 8 9 10

a b c d e

hello world and awk
languege php,java,python
LANGUEGE PHP,JAVA,PYTHON
[root@node4 ~]#

6.现在a b c d e这行前后都有空行,如果再次给每行加一行空行,a b c d e前后就会各自出现两行空行。现在用一下命令,不管文本内原本有没有空行,都保证文本每行之间只有一个空行。其实说白了也就是先删掉原本存在的所有空行,再给每一行文本后面增加一行空行。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
[root@node4 ~]# sed -i '/^$/d;G' 1.txt 
[root@node4 ~]# cat 1.txt
1 2 3 4 5

6 7 8 9 10

a b c d e

hello world and awk

languege php,java,python

LANGUEGE PHP,JAVA,PYTHON

[root@node4 ~]#

本篇到此结束

欢迎打赏,谢谢
------ 本文结束------
0%