9.sed

作用:

  • 模糊过滤文件的内容
  • 查找指定的行
  • 对文件进行增删改查
  • 替换
  • 格式化输出内容,后向引用

格式:

  • grep ‘过滤内容’ 文件
  • sed ‘/过滤内容/‘ 文件
  • sed ‘模式 动作’ 文件:模式查找谁,动作做什么事

指定行查找

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
# 显示最后一行
sed -n '3p' test.txt
# 默认会每一行每一行的默认输出,到第3行输出并执行动作输出
# 意思就是例如我修改第3行,先1-2-3-3-4-5,修改前输出一次3,修改后输出一次3,-n就是取消默认输出,有-n就要有-p
# 这会导致每一行都输出显示到屏幕上,-n取消默认输出,只输出执行动作的输出
# p是动作,print打印输出


# 显示倒数第一行
sed -n '$p' test.txt

# 显示文件的2-4行
sed -n '2,4p' test.txt

# 显示文件第二行到最后一行
sed -n '2,$p' test.txt

# 处理文件内容
ifconfig ens33 |sed -n '2p'

模糊过滤

:找到匹配成功的

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
结构: sed -n '/过滤内容/p' file

正则使用

sed -n '/^a/p' test.txt # 匹配a开头的行
sed -n '/^[abc]/p' test.txt # a或b或c开头的行
sed -n '/h$/p' # 过滤以h结尾的行

# 过滤区间
# bin开头到adm匹配的行区间范围,行区间
sed -n '/^bin/,/adm/p' test.txt

# 查看日志19:00:01到21:50:01区间
sed -n '/19:00:01/,/21:50:01/p' /var/log/message


# 先找到aaa,再找bbb即一个区间,重复aaa,如果后面找到aaa了没有bbb,就直接aaa到末尾输出,开头到下一个开头没有结尾也是输出
sed -n '/aaa/,/bbb/p' test.txt

sed删除

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
sed '3d' test.txt # 删除第3行,输出结果,默认不修改源文件

sed -i ‘3d' test.txt # 修改test.txt删除

# 删除2-4行
sed ’2,4d' test.txt

# 模糊过滤并删除
sed '/root/d' /etc/passwd # 删除包含root的行

# sed -r支持扩展正则
sed -rn '/^bin|^lp/p' test.txt
sed -r '/^bin|^lp/d' test.txt # 删除bin或lp开头的行


# 区间删除
sed '/^bin/,/^adm/d' test.txt

sed替换

语法结构:

  • sed ‘s###g’ 文件,一般使用这个,因为用/可能某些使用/需要\麻烦一些
  • sed ‘s@@@g’ 文件
  • sed ‘s///g’ 文件

:vim中的s是指检测到的第一个行进行替换,%s指每个行;而这里s是指全部行

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
# 替换每行的第一个单词
sed 's#root#demo#' test.txt # 只替换每行的第一个root单词

# 替换每行全部单词
sed 's#root#demo#g' test.txt # 替换每行的每一个root

# 正则表达式替换,输出禁用selinux的文本,没加-i不会修改
sed -r 's/^(selinux=).*/\1disabled/g' /etc/sysconfig/selinux


# 统计/etc/passwd每个单词出现的次数
sed 's#[:/0-9x]# #g' /etc/passwd |xargs -n1 |sort|uniq -c|sort -rn|head

# bin替换成demo,\b边界
sed 's#\bbin\b#demo#g' # 只有检测到bin这个单词才能替换成demo
# 同
sed 's#\<bin\>#demo#g' # 只有检测到bin这个单词才能替换成demo
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
动作:
sed -n '3p' 文件
sed '3d' 文件
sed 's###g' 文件

模式+动作:
模式:找谁,如何找
sed -n '3p' # 找到第三行,p进行print打印输出
# 将第三行的^root开头的root替换成demo
sed '3s#^root#demo#g' test
# 1-4行替换
sed '1,4s#root#demo#g' test
# 替换adm出现的行替换adm为demo
sed '/adm/s#adm#demo#g' test
# 区间替换
sed '/adm/,/lp/s#[a-z]# #g' test

例如:
sed '/SELINUX\=/#disabled#enforcing#g' /etc/selinux/config

sed追加 插入 替换 后向引用

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
# i插入      ;vim的O插入模式
sed '3i aaa' test.txt # 插入aaa到第三行(第三行变为aaa,原本的变为第四行)

# a追加 ;vim的o插入模式
sed '3a aaa' test.txt # 插入aaa到第三行的下一行

# c替换 ;vim的C插入模式
sed '3c aaa' test.txt # 第三行被替换成aaa

# w保存
sed -n '4w new.txt' test.txt # 将test.txt的第4行保存到new.txt

# 后向引用
结构:sed s#()()()#\1\2\3#g

sed -r 's#(.*)#\1#g' test.txt # 就是每行处理读取(匹配的)替换为\1调用的(匹配的)字符

sed -r 's#(.*)#\1 nihao#g' test.txt
sed -r 's#(.*)#print("\1\\n");#g' test.txt # 给前后添加print("内容\n")

eg

1
seq 5|sed -r 's#(.*)#useradd test\1#g'|bash