shell实战正则三贱客——sed

发布时间 2023-12-15 14:19:19作者: WeChat2834
shell实战正则三贱客——sed

特点及格式

  • sed stream editor:流编辑器,sed把处理的内容(文件),当做是水,源源不断的进行处理,一行一行读取文件,直到文件末尾。
  • sed 格式
命令 选项 sed命令功能 说明 参数
sed -r 's#oldboy#oldgirl#g' 单引号里面的s表示替换功能;g表示一个修饰符 oldboy.txt
-i 修改文件
-r 支持扩展正则
  • sed 命令功能 :增删改查
功能
s 替换(substitute sub)
p 显示(print),(应该是按行展示,一般跟上-n)
d 删除delete (已行为单位)
cai 增加c/a/i

sed的执行过程

  • 四个字描述:老厉害了 '找谁干啥'
  • 找谁:你要哪一行
  • 干啥:增删改查

执行过程说明

image-20231215141326077

1.录入命令 sed -n '3p' oldboy.txt

2.系统按行录入oldboy.txt

3.系统判断该行是否满足条件 ('3p' );

4.如果不满足且没加 -n 则 默认输出到屏幕,然后处理下一行;如果不满足 且 加上了 -n 则直接处理下一行,循环继续判定。

5.如果条件满足 ,则执行对应的增删改查命令(p d s a i c ) p是显示,就会输出到屏幕一次。如果没加-n又会输出到屏幕 ,执行下一行循环,如果加了-n则不输出到屏幕执行下一次循环

6.循环执行,直至结果结束

####sed默认输出,啥都不加
[root@localhost tmp]# sed   '' test_function.sh
#!/bin/bash
#
function sayHello {

	echo "hello world 1"
	return 113 
}

sayHello
[root@localhost tmp]# 
[root@localhost tmp]# sed   '3p' test_function.sh
#!/bin/bash
#
function sayHello {       ####因为p是查询显示
function sayHello {       ###不加n会把内容显示出来

	echo "hello world 1"
	return 113 
}

sayHello
[root@localhost tmp]# sed  -n  '3p' test_function.sh
function sayHello {
[root@localhost tmp]# 

sed的核心应用

查找

查找格式
'1p' '2p' 指定行号进行查找, $表示最后一行
'1,5p' 指定行号范围进行查找
'/hello/p' 类似与grep,过滤//里面可以写正则
(注意sed命令默认不支持扩展正则,如果要使用加上-r参数
'/10:00/,/11:00/'p 表示范围的过滤
'1,/hello/'p 也可以混合一起使用,行号和过滤
[root@localhost tmp]# sed  -n  '/{/,/}/p' test_function.sh
function sayHello {

	echo "hello world 1"
	return 113 
}

  • 指定行号
####sed默认输出,啥都不加
[root@localhost tmp]# sed   '' test_function.sh
#!/bin/bash
#
function sayHello {

	echo "hello world 1"
	return 113 
}

sayHello
[root@localhost tmp]# 
[root@localhost tmp]# sed   '3p' test_function.sh
#!/bin/bash
#
function sayHello {       ####因为p是查询显示
function sayHello {       ###不加n会把内容显示出来

	echo "hello world 1"
	return 113 
}

sayHello
[root@localhost tmp]# sed  -n  '3p' test_function.sh
function sayHello {
[root@localhost tmp]# 
[root@localhost tmp]# sed -n  '$p' test_function.sh  #######$表示最后一行
sayHello
[root@localhost tmp]# 

  • 过滤(注意sed命令默认不支持扩展正则,如果要使用加上-r参数)
[root@localhost tmp]# sed -nr  '/[0-9]{3}/p' test_function.sh
	return 113 
[root@localhost tmp]# [root@localhost tmp]# sed -n  '/function/p' test_function.sh
function sayHello {
[root@localhost tmp]#
[root@localhost tmp]# sed -n  '/[31]/p' test_function.sh
	echo "hello world 1"
	return 113 
[root@localhost tmp]#[root@localhost tmp]# sed -n   '/[0-9]{3}/p' test_function.sh ######匹配失败查询不出来数据
[root@localhost tmp]# 
 [root@localhost tmp]# sed -nr  '/[0-9]{3}/p' test_function.sh
	return 113 
[root@localhost tmp]# 


sed命令 的那些事儿

  1. 表示范围过滤的时候,如果结尾的内容匹配不到就会一直显示到最后一行

删除

  • d delet

d是整行删除。

把上面的查找格式p改成d就行

删除格式
'1d' '2d' 指定行号进行删除, $表示最后一行
'1,5d' 指定行号范围进行删除
'/hello/d' 类似与grep,过滤//里面可以写正则
(注意sed命令默认不支持扩展正则,如果要使用加上-r参数
'/10:00/,/11:00/'d 表示范围的过滤
'1,/hello/'d 也可以混合一起使用,行号和过滤
  • 企业案例 :删除文件中的空行和包含#号的行
#删除文件中的空行和包含#号的行
[root@localhost sed]# sed -E '/(^$)|#/'d settst01.txt 
1 2 3
4 5 6
7 8 9
10 11 12
13 14 15
16 17 18
25 26 27
28 29 30
.....
100
[root@localhost sed]# 
####删除全是#的行
[root@localhost sed]# sed -E '/^[#]+$/'d settst01.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 26 27
28 29 30
31 32 33
34 35 36

37 38 39
40 41 42
43 44 45
46 47 48
49 50 51
..........
100
[root@localhost sed]# ##
#######!的妙用,不显示,就算删除
[root@localhost sed]# sed  -En '/(^$)|#/!p' settst01.txt 
1 2 3
4 5 6
7 8 9
10 11 12
13 14 15
16 17 18
.........
31 32 33
34 35 36
37 38 39
40 41 42
43 44 45
46 47 48
49 50 51
52 53 54
55 56 57
58 59 60
61 62 63
64 65 66
...........
100
[root@localhost sed]# 

cai增加

命令
c replace 替代这行类容
a append 追加,向指定行或每一行追加内容(往后)
i insert 插入,向指定行或每一行插入内容(向前)

案例:像文件中追加多行内容

向文件confgs 里面追加
UserDNS NO
GSSAPIAUTCATION no
pERMITrootLogin no

###方法1 :
cat  >>config<<  'EOF'  ###如果内容又特殊符号加上''
UserDNS NO
GSSAPIAUTCATION no
pERMITrootLogin no
EOF
###方法2
sed '$a UserDNS NO\n  GSSAPIAUTCATION no\n GSSAPIAUTCATION no\n'

注意,如果要修改文件内容加上参数 -i 就能修改文件

sed-替换s

  • s sub substitute 替换
  • g global全局替换,sed默认只替换每行第一个匹配的内容,加上g就全局匹配每一个匹配的
替换格式
s###g
s///g
s@@@

注意:s和g间的符号理论可以是任意符号,最好找没特殊意义的,常用是###,///,@@@

###每一行开头加上#
[root@localhost sed]# sed 's@^@#@' settst01.txt 
 sed 's@^@#@' settst01.txt 
#1 2 3
#4 5 6
#7 8 9
#
#
#10 11 12
#
....
[root@localhost sed]#
[root@localhost sed]# sed  's@#@@' settst01.txt    ######只去掉开头的#,所以匹配一次就行不用加上g
1 2 3
4 5 #6
7# 8 9


10 11 12

13 14 15
....
[root@localhost sed]#  ####如果要修改文件加上 -i

  • 后向引用,反向引用

​ 口诀:先保护,再使用

####处理123456一串数字
[root@localhost sed]# echo "123456" |sed  -r 's#(.*)#<\1>#'   #####\1对应前面小括号数包含的一个区域
<123456>
[root@localhost sed]# echo "123456" |sed  -r 's#([0-9]{3})(.*)#\1_\2_#'
123_456_
[root@localhost sed]# 
[root@localhost sed]# echo "hell_word"|sed -r 's@(^.*)(_)(.*$)@\3\2\1@'
word_hell
[root@localhost sed]# 

注意:有规律的可以直接用替换,没规律的就可以用这种后向引用

帮助信息 man sed

找详细的帮助信息 info sed

####案例获取ip,自个写 的获取的多行
[root@localhost sed]# ip a|sed  -n '/inet/p'|sed -r 's@([ ]+) ([a-zA-Z0-9]+)( )([0-9.:/]+)( .*)@\4@'
127.0.0.1/8
::1/128
192.168.43.164/24
    inet6 2409:8962:5009:1015:6489:df1c:be22:3e77/64 scope global noprefixroute dynamic 
    inet6 fe80::16b:3a6b:a100:94fc/64 scope link noprefixroute 
192.168.122.1/24
######靠谱答案
[root@localhost sed]# ip a s lo   ####指定lo这块网卡
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000
    link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
    inet 127.0.0.1/8 scope host lo
       valid_lft forever preferred_lft forever
    inet6 ::1/128 scope host 
       valid_lft forever preferred_lft forever
[root@localhost sed]# 

[root@localhost sed]# ip a s lo|sed -n '3p'|sed  -r 's/(^.*t )([0-9.]+)(.*)/\1/'  ###先取指定行,再处理 
    inet 
[root@localhost sed]# ip a s lo|sed -n '3p'|sed  -r 's/(^.*t )([0-9.]+)(.*)/\2/'  ####(^.*t ) 这里面的t空格就是考虑到正则匹配的贪婪性,不能只写空格,他会一直匹配下去
127.0.0.1
[root@localhost sed]# ip a s lo|sed -n '3p'|sed  -r 's/(^.*t )([0-9.]+)(.*)/\3/'
/8 scope host lo
[root@localhost sed]# 

注意:命令结果中如果有相应的内容,优先看命令帮助,是否通过命令参数可直接提取出来,不要急着使用管道或者三剑客

stat命令是看文件属性