sed编辑器学习

sed原理和过程

编辑器将文本内容读入内存,修改后再写回文件

学习教程

参数选项

参数选项 解释
-n 取消默认sed输出,经常与sed内置命令p一起用
-i 直接修改结果写入文件,没有这个,sed修改的就是内存数据, 修改内容要加这个选项
-e 多次编辑,不需要管道符
-r 支持正则扩展

内置命令

sed命令字符 解释
a append,文本追加
d delete ,删除匹配行
i insert, 指定行插入文本
p print,打印匹配行,常与-n一起用
s/正则/替换内容/g **匹配内容,然后替换,**结尾g代表全局匹配
s### 或者s@@@ 同上 ,可以把 / 改为 #

sed匹配范围

范围 解释
空地址 全文处理
单地址 指定文件某一行
/pattern/ 被模式匹配到的每一行
范围长度 10,20,表示10-20行,10,+5 表示10 向下5行
步长 1~2 表示1,3,5,7,9

sed使用方法总结

使用方法 解释
去头去尾法 一次去头,一次去尾
-e参数多次编辑 设置 -e 之后,可以反复使用,不用管道重复 调用 sed命令

打印行

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
lyr@DESKTOP-FSVN6C0:~/tmp$ cat -n temp | sed -n '10,+3p'
    10  news❌9:9:news:/var/spool/news:/usr/sbin/nologin
    11  uucp❌10:10:uucp:/var/spool/uucp:/usr/sbin/nologin
    12  proxy❌13:13:proxy:/bin:/usr/sbin/nologin
    13  www-data❌33:33:www-data:/var/www:/usr/sbin/nologin
lyr@DESKTOP-FSVN6C0:~/tmp$ cat -n temp | sed -n '10,13p'
    10  news❌9:9:news:/var/spool/news:/usr/sbin/nologin
    11  uucp❌10:10:uucp:/var/spool/uucp:/usr/sbin/nologin
    12  proxy❌13:13:proxy:/bin:/usr/sbin/nologin
    13  www-data❌33:33:www-data:/var/www:/usr/sbin/nologin

修改单词

1
2
3
4
5
6
 sed "s/my/My/p" temp -n
 # 将 temp 文件 小写的 my 改为大写的 My 
 
lyr@DESKTOP-FSVN6C0:~/tmp$ sed "s#My#my#p" temp -n
my name is lyr
my website is lyr-2000.xyz
1
2
3
4
5
6
7
8
9
lyr@DESKTOP-FSVN6C0:~/tmp$ sed "a -----------------" temp
hello
-----------------
My name is lyr
-----------------
i teach linux
-----------------
My website is lyr-2000.xyz
-----------------

获取 linux ip地址

1
2
3
4
5
6
7
8
9
ifconfig | sed "s/^.*inet //p" -n | sed 's/net.*$//p' -n
172.27.115.56
127.0.0.1

# 思路: 先匹配 inet , 然后 在 匹配 netmask 结尾的行,然后

# 上面使用 去头去尾的管道法实现
# 下面采用 -e 参数 来实现
ifconfig | sed -ne 's/^.*inet\s//' -e 's/\snetmask.*$//p'

获取mtu

1
2
3
4
5
6
7
8
ifconfig | sed 's/mtu//p' -n | sed 's/.*>   //p' -n
 ifconfig | sed 's/mtu//p' -n | sed 's/.*>\s*//p' -n
# 匹配 1500
ifconfig | sed 's/mtu//p' -n | sed 's/.*>   //p' -n | sed '1p' -n

# 上面是使用管道实现的,这里使用 -e 参数实现

ifconfig | sed -ne 's/mtu//g'  -e 's/.*> \s*//gp'

使用案例

shell sed 学习

既然 sed 和awk都是Linux常见的命令,也是处理文件的常用的命令,但是两者还有哪些区别(除了 sed 一般对行进行操作,awk 对列进行操作)?

多操作几次,亲自感受比什么都清晰。

要说区别,说来说去,还就是行和列。

sed读取一行,以行作为单位,进行处理。

awk读取一行,切割成字段,以字段为单位,进行细节处理。

不过因为正则的特性以及这两种工具内的逻辑,sed和awk基本都能互相替代,只不过sed能简单处理的换成awk可能很复杂,awk能简单处理的换成sed可能会很复杂。

一般来说,sed+cut和awk功能上比较接近。perl则等于sed+awk+grep+cut+……

sed(stream editor) 流编辑器, 对标准输入逐行读取

  • 第一种形式 stdout | sed [option] “pattern comand”
  • 第二种形式 sed [option] “pattern command” file

image-20211003224528891

 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
lyr@DESKTOP-FSVN6C0:~$ cat app.sh  | sed -n '/#/p'
#!/bin/bash
#Author:LYR
#Time:2021-10-03 17:35:05
#Name:app.sh
lyr@DESKTOP-FSVN6C0:~$ cat app.sh  | sed  '/#/p'
#!/bin/bash
#!/bin/bash
#Author:LYR
#Author:LYR
#Time:2021-10-03 17:35:05
#Time:2021-10-03 17:35:05
#Name:app.sh
#Name:app.sh









awk 'BEGIN{w=20;num="hello";w++; print num,w}';



lyr@DESKTOP-FSVN6C0:~$ sed -n -e '/#/p' -e '/print/p' app.sh
#!/bin/bash
#Author:LYR
#Time:2021-10-03 17:35:05
#Name:app.sh
awk 'BEGIN{w=20;num="hello";w++; print num,w}';

# 这里我们可以看到 , 多个匹配模式 可以用 -e
# 有点类型 grep

我们可以看到 ,如果 不加 -n 就会打印2次, 加 -n 表示静默模式, 就只打印匹配的行

1
2
3
4
5
6
7
8
lyr@DESKTOP-FSVN6C0:~$ echo "pythondd " > app.sh

lyr@DESKTOP-FSVN6C0:~$ sed -n -f edit.sed  app.sh
pythondd
lyr@DESKTOP-FSVN6C0:~$ echo "love  " >> app.sh
lyr@DESKTOP-FSVN6C0:~$ sed -n -f edit.sed  app.sh
pythondd
lyr@DESKTOP-FSVN6C0:~$

pattern详解

image-20211003225003050

练习

  1. 将 python 变为 PYTHON
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
lyr@DESKTOP-FSVN6C0:~$ cat app.sh && echo "-----------" &&  sed -n -i  's/python/PYTHON/g;p'  app.sh  && cat app.sh
pythondd
love
-----------
PYTHONdd
love
lyr@DESKTOP-FSVN6C0:~$
# -i 参数就是直接修改文件
# -i 等于就是把输出,直接盖掉 app.sh , 如果不加 -n ,就会越来越多
# ;p 的话就是 print 打印
1
2
3
4
5
lyr@DESKTOP-FSVN6C0:~$ echo "python i love it " > app.sh
lyr@DESKTOP-FSVN6C0:~$ cat app.sh && echo "-----------" &&  sed  -n -i  's/python/PYTHON/g;p'  app.sh  && cat app.sh
python i love it
-----------
PYTHON i love it

sed 一般就直接修改文件比较爽

打印 10-20行

 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
lyr@DESKTOP-FSVN6C0:~$ sed -n '17p' /etc/passwd
gnats❌41:41:Gnats Bug-Reporting System (admin):/var/lib/gnats:/usr/sbin/nologin
lyr@DESKTOP-FSVN6C0:~$ sed -n '10,20p' /etc/passwd
news❌9:9:news:/var/spool/news:/usr/sbin/nologin

lyr@DESKTOP-FSVN6C0:~$ sed -n '10,+3p' /etc/passwd
news❌9:9:news:/var/spool/news:/usr/sbin/nologin
uucp❌10:10:uucp:/var/spool/uucp:/usr/sbin/nologin
proxy❌13:13:proxy:/bin:/usr/sbin/nologin
www-data❌33:33:www-data:/var/www:/usr/sbin/nologin
# 打印 第10 行 ,再 + 3行

lyr@DESKTOP-FSVN6C0:~$ sed -n "/bash/p" /etc/passwd
root❌0:0:root:/root:/bin/bash
lyr❌1000:1000:,,,:/home/lyr:/bin/bash
# 打印 包含 bash字符串的

lyr@DESKTOP-FSVN6C0:~$ sed -n "/\/bash/p" /etc/passwd
root❌0:0:root:/root:/bin/bash
lyr❌1000:1000:,,,:/home/lyr:/bin/bash
# 打印 包含 /bash 字符串的文本


 sed -n '4,/^lyr/p' /etc/passwd
 # 从第4行开始,直到找到 lyr 开头的行
 
lyr@DESKTOP-FSVN6C0:~$ a=4
lyr@DESKTOP-FSVN6C0:~$ sed -n "$a,5p" /etc/passwd
sys❌3:3:sys:/dev:/usr/sbin/nologin
sync❌4:65534:sync:/bin:/bin/sync
# 打印  4-5行

sed 编辑命令详解

image-20211003230148031

image-20211003230203134

 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
lyr@DESKTOP-FSVN6C0:~$ head -n 1 passwd  && echo "=====" && sed -i '1d' passwd  && head -n 1 ./passwd
bin❌2:2:bin:/bin:/usr/sbin/nologin
=====
sys❌3:3:sys:/dev:/usr/sbin/nologin
# 这里 调用 d 直接 删除 第一行,然后 打印的就是 第二行了

# 删除第1行到 第3行


lyr@DESKTOP-FSVN6C0:~$ head -n 4 passwd  && echo "=====" && sed -i '1,3d' passwd  && head -n 4 ./passwd
sys❌3:3:sys:/dev:/usr/sbin/nologin
sync❌4:65534:sync:/bin:/bin/sync
games❌5:60:games:/usr/games:/usr/sbin/nologin
man❌6:12:man:/var/cache/man:/usr/sbin/nologin
=====
man❌6:12:man:/var/cache/man:/usr/sbin/nologin
lp❌7:7:lp:/var/spool/lpd:/usr/sbin/nologin
mail❌8:8:mail:/var/mail:/usr/sbin/nologin
news❌9:9:news:/var/spool/news:/usr/sbin/nologin

# 这里 我们就删除了 1-3 行了


# 删除 所有 /sbin/nologin

lyr@DESKTOP-FSVN6C0:~$ head -n 4 ./passwd  && echo "=====" && sed -i '/\/sbin\/nologin/d' passwd
  && head -n 4 ./passwd
  
man❌6:12:man:/var/cache/man:/usr/sbin/nologin
lp❌7:7:lp:/var/spool/lpd:/usr/sbin/nologin
mail❌8:8:mail:/var/mail:/usr/sbin/nologin
news❌9:9:news:/var/spool/news:/usr/sbin/nologin
=====
tss❌106:111:TPM software stack,,,:/var/lib/tpm:/bin/false
pollinate❌111:1::/var/cache/pollinate:/bin/false
lyr❌1000:1000:,,,:/home/lyr:/bin/bash
postgres❌1001:1001::/home/postgres:/bin/sh

直接追加内容

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
postgres❌1001:1001::/home/postgres:/bin/sh
lyr@DESKTOP-FSVN6C0:~$ head -n 4 ./passwd  && echo "=====" && sed -i '/lyr/a it is me!!!' passwd  && head -n 4 ./passwd

tss❌106:111:TPM software stack,,,:/var/lib/tpm:/bin/false
pollinate❌111:1::/var/cache/pollinate:/bin/false
lyr❌1000:1000:,,,:/home/lyr:/bin/bash
postgres❌1001:1001::/home/postgres:/bin/sh
=====
tss❌106:111:TPM software stack,,,:/var/lib/tpm:/bin/false
pollinate❌111:1::/var/cache/pollinate:/bin/false
lyr❌1000:1000:,,,:/home/lyr:/bin/bash
it is me!!!
# 匹配到 lyr 这行后,后面追加 it is me!!

image-20211003231613473

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
lyr@DESKTOP-FSVN6C0:~$ echo "hadoop python" > passwd
lyr@DESKTOP-FSVN6C0:~$ cat passwd && sh ./app.sh && cat passwd
hadoop python
HADOOP python
lyr@DESKTOP-FSVN6C0:~$ cat app.sh
#!/bin/bash
#Author:LYR
#Time:2021-10-03 23:24:40
#Name:app.sh


old_str=hadoop
new_str=HADOOP


sed -i "s/$old_str/$new_str/g" ./passwd