29_sed

发布时间 2023-10-22 00:41:06作者: 鸟叔书

一. Sed 的用法举例(逐行处理)

1. p => print 打印
# 1. p => print 打印
[root@kvm ckh]# cat 1.txt
aaabbb
bbbccc
cccddd
dddeee
eeefff
mmnnmmnn
zzkkkzzk
[root@kvm ckh]#
[root@kvm ckh]# sed -n '1p' 1.txt        # 打印第1行
aaabbb
[root@kvm ckh]#
[root@kvm ckh]# sed -n '3p' 1.txt        # 打印第3行
cccddd
[root@kvm ckh]# sed -n '1,3p' 1.txt      # 打印第1-3行
aaabbb
bbbccc
cccddd
[root@kvm ckh]#
[root@kvm ckh]# sed -n '1p;3p' 1.txt     # 打印第1、3行
aaabbb
cccddd
[root@kvm ckh]# sed -n '2,+2p' 1.txt     # 打印第2行以及后面紧跟的2行
bbbccc
cccddd
dddeee
[root@kvm ckh]#
[root@kvm ckh]# sed -n '1~2p' 1.txt      #  打印奇数行
aaabbb
cccddd
eeefff
zzkkkzzk
[root@kvm ckh]# sed -n '2~2p' 1.txt      # 打印偶数行
bbbccc
dddeee
mmnnmmnn

# 2. p => print 打印 + 搜索
[root@kvm ckh]# cat 1.txt
aaabbb
bbbccc
cccddd
dddeee
eeefff
mmnnmmnn
zzkkkzzk
[root@kvm ckh]# sed -n '/d/p' 1.txt       # 打印包含字母d的行
cccddd
dddeee
[root@kvm ckh]# sed -n '/fff$/p' 1.txt    # 以fff结尾的行
eeefff
[root@kvm ckh]# sed -n '/^b/p' 1.txt      # 以b开头的行
bbbccc
[root@kvm ckh]# sed -n '/^b/!p' 1.txt     # 打印非b开头的行
aaabbb
cccddd
dddeee
eeefff
mmnnmmnn
zzkkkzzk
[root@kvm ckh]# grep -v "^b" 1.txt
aaabbb
cccddd
dddeee
eeefff
mmnnmmnn
zzkkkzzk
[root@kvm ckh]# sed -n '$=' 1.txt         # 打印总行数
7
[root@kvm ckh]# cat 1.txt | wc -l
7
2. d => delete
[root@kvm ckh]# cat 1.txt
aaabbb
bbbccc
cccddd
dddeee
eeefff
mmnnmmnn
zzkkkzzk
[root@kvm ckh]# sed '/c/d' 1.txt           # 删除包含c的行
aaabbb
dddeee
eeefff
mmnnmmnn
zzkkkzzk
[root@kvm ckh]#
[root@kvm ckh]# sed '2,4d' 1.txt          # 删除 2-4行
aaabbb
eeefff
mmnnmmnn
zzkkkzzk
[root@kvm ckh]# sed '2d;4d' 1.txt         # 删除第2、4行
aaabbb
cccddd
eeefff
mmnnmmnn
zzkkkzzk
[root@kvm ckh]# sed '/^e/!d' 1.txt       # 删除不是以e开头的行
eeefff
[root@kvm ckh]#
[root@kvm ckh]# sed '$d' 1.txt           # 删除最后一行
aaabbb
bbbccc
cccddd
dddeee
eeefff
mmnnmmnn
[root@kvm ckh]# sed '/^$/d' 1.txt       # 删除空行
3. s => substitute 替换
[root@kvm ckh]# cat 1.txt
aaabbb
bbbccc
cccddd
dddeee
eeefff
mmnnmmnn
zzkkkzzk
[root@kvm ckh]#
[root@kvm ckh]# sed 's/b/A/' 1.txt      # 默认将每行第1个b替换成A
aaaAbb
Abbccc
cccddd
dddeee
eeefff
mmnnmmnn
zzkkkzzk
[root@kvm ckh]# sed 's/b/A/2' 1.txt     # 将每行第2个b替换成A
aaabAb
bAbccc
cccddd
dddeee
eeefff
mmnnmmnn
zzkkkzzk
[root@kvm ckh]# sed 's/b/A/g' 1.txt    # 将每行所有的b替换成A
aaaAAA
AAAccc
cccddd
dddeee
eeefff
mmnnmmnn
zzkkkzzk
[root@kvm ckh]# sed 's/bb/A/g' 1.txt   # 将每行所有的bb替换成A
aaaAb
Abccc
cccddd
dddeee
eeefff
mmnnmmnn
zzkkkzzk
[root@kvm ckh]# sed 's/b//g' 1.txt    # 删除每行所有的b
aaa
ccc
cccddd
dddeee
eeefff
mmnnmmnn
zzkkkzzk
[root@kvm ckh]# sed 's/b//2' 1.txt   # 删除每行第2个b
aaabb
bbccc
cccddd
dddeee
eeefff
mmnnmmnn
zzkkkzzk
[root@kvm ckh]# cat 1.txt
aaabbb
bbbccc
cccddd
dddeee
eeefff
mmnnmmnn
zzkkkzzk
[root@kvm ckh]# sed '1,3s/^/#/' 1.txt  # 1-3行加注释
#aaabbb
#bbbccc
#cccddd
dddeee
eeefff
mmnnmmnn
zzkkkzzk
[root@kvm ckh]# cat -A 1.txt
aaabbb$
bbbccc$
cccddd$
dddeee$
eeefff$
mmnnmmnn$
zzkkkzzk$
[root@kvm ckh]# sed '1,3s/$/!/' 1.txt # 1-3行尾部加!号
aaabbb!
bbbccc!
cccddd!
dddeee
eeefff
mmnnmmnn
zzkkkzzk
[root@kvm ckh]# cat 1.txt
99aaa99bbb
bbb99ccc
cccddd
d99dde99ee
eee88fff
mmnnmmnn
zz88kkk8899zzk
[root@kvm ckh]# sed -n 's/99//2p' 1.txt     # 把每行第2个99删掉并只输出修改过的行
99aaabbb
d99ddeee
[root@kvm ckh]#
[root@kvm ckh]# sed -n 's/99//2p' 1.txt | tr [a-z] [A-Z] # 同上,并且小写转大写
99AAABBB
D99DDEEE
[root@kvm ckh]# sed -n 's/99//2p' 1.txt | tr [1-9] A     # 同上,并且9替换成A
AAaaabbb
dAAddeee
[root@kvm ckh]# cat 1.txt
99aaa99bbb
bbb99ccc
cccddd
d99dde99ee
eee88fff
mmnnmmnn
zz88kkk8899zzk
root:x:0:0:root:/root:/bin/bash        # 处理这行有 /
[root@kvm ckh]#
[root@kvm ckh]# sed 's#/#A#g' 1.txt    # 用 # 或者任意字符代替分割符
99aaa99bbb
bbb99ccc
cccddd
d99dde99ee
eee88fff
mmnnmmnn
zz88kkk8899zzk
root:x:0:0:root:Aroot:AbinAbash
[root@kvm ckh]# cat 1.txt
99aaa99bbb
bbb99ccc
cccddd
d99dde99ee
eee88fff
mmnnmmnn
zz88kkk8899zzk
root:x:0:0:root:/root:/bin/bash
[root@kvm ckh]# # -r regexp
[root@kvm ckh]# sed -r 's/(^b{3})(9{2})(.*)(c$)/\1\3\4\2/' 1.txt  # 第二行ccc和99互换位置
99aaa99bbb
bbbccc99
cccddd
d99dde99ee
eee88fff
mmnnmmnn
zz88kkk8899zzk
root:x:0:0:root:/root:/bin/bash
[root@kvm ckh]#
[root@kvm ckh]# sed -r 's/(^b{3})(9{2})(.*)(c$)/\1\4\2\3/' 1.txt  # 参考上面
99aaa99bbb
bbbc99cc
cccddd
d99dde99ee
eee88fff
mmnnmmnn
zz88kkk8899zzk
root:x:0:0:root:/root:/bin/bash
[root@kvm ckh]# sed -r 's/(^.)(.*)(e$)/\3\2\1/' 1.txt   # 第3行首尾字母交换位置
99aaa99bbb
bbb99ccc
cccddd
e99dde99ed
eee88fff
mmnnmmnn
zz88kkk8899zzk
root:x:0:0:root:/root:/bin/bash

# 达到 grep -v 一样的效果
[root@kvm ckh]# cat 1.txt
99aaa99bbb
bbb99ccc
#

cccddd

d99dde99ee
eee88fff
mmnnmmnn
zz88kkk8899zzk
root:x:0:0:root:/root:/bin/bash
[root@kvm ckh]#
[root@kvm ckh]# grep -E -v "^#|^$" 1.txt
99aaa99bbb
bbb99ccc
cccddd
d99dde99ee
eee88fff
mmnnmmnn
zz88kkk8899zzk
root:x:0:0:root:/root:/bin/bash
[root@kvm ckh]#
[root@kvm ckh]# sed '/^#/d;/^$/d' 1.txt
99aaa99bbb
bbb99ccc
cccddd
d99dde99ee
eee88fff
mmnnmmnn
zz88kkk8899zzk
root:x:0:0:root:/root:/bin/bash

# 删除开头的数字和开头的空格
[root@kvm ckh]# cat 1.txt
99aaa99bbb
bbb99ccc
#
  abc

cccddd

d99dde99ee
eee88fff
mmnnmmnn
zz88kkk8899zzk
root:x:0:0:root:/root:/bin/bash
[root@kvm ckh]# sed 's/^[1-9]\+//' 1.txt  # 删除数字开头的行,多个数字
aaa99bbb
bbb99ccc
#
  abc

cccddd

d99dde99ee
eee88fff
mmnnmmnn
zz88kkk8899zzk
root:x:0:0:root:/root:/bin/bash
[root@kvm ckh]#
[root@kvm ckh]# sed 's/^[1-9]\+//;s/^[ ]\+//' 1.txt
aaa99bbb
bbb99ccc
#
abc

cccddd

d99dde99ee
eee88fff
mmnnmmnn
zz88kkk8899zzk
root:x:0:0:root:/root:/bin/bash
[root@kvm ckh]# sed 's/^[1-9]\+//;s/^[ \t]\+//' 1.txt
aaa99bbb
bbb99ccc
#
abc

cccddd

d99dde99ee
eee88fff
mmnnmmnn
zz88kkk8899zzk
root:x:0:0:root:/root:/bin/bash
[root@kvm ckh]# sed 's/^[1-9]\{2\}//;s/^[ \t]\+//' 1.txt
aaa99bbb
bbb99ccc
#
abc

cccddd

d99dde99ee
eee88fff
mmnnmmnn
zz88kkk8899zzk
root:x:0:0:root:/root:/bin/bash
# 用 space 代替 " " 和 \t
[root@kvm ckh]# sed 's/^[1-9]\{2\}//;s/^[[:space:]]\+//' 1.txt
aaa99bbb
bbb99ccc
#
abc

cccddd

d99dde99ee
eee88fff
mmnnmmnn
zz88kkk8899zzk
root:x:0:0:root:/root:/bin/bash
# [:alnum:] 所有的字母和数字
# [:alpha:] 所有的字母
# [:blank:] 所有呈水品呈现的空白字符
# [:cntrl:] 所有的控制字符
# [:digit:] 所有的数字
# [:graph:] 所有的打印字符,不包含空格
# [:lower:] 所有的小写字母
# [:print:] 所有的可打印字符,包括空格
# [:punct:] 所有的标点字符
# [:space:] 所有呈水平、或垂直排列的空白字符
# [:upper:] 所有的大写字母
# [:xdigit:] 所有的16进制数
#  [=字符=]   所有和指定字符串相等的字符

# 给首字母、所有字母加()
[root@kvm ckh]# cat 1.txt
99aaa99bbb
bbb99ccc
#
  abc

cccddd

d99dde99ee
eee88fff
mmnnmmnn
zz88kkk8899zzk
root:x:0:0:root:/root:/bin/bash
[root@kvm ckh]#
[root@kvm ckh]# sed -r 's/([a-z])/(\1)/' 1.txt
99(a)aa99bbb
(b)bb99ccc
#
  (a)bc

(c)ccddd

(d)99dde99ee
(e)ee88fff
(m)mnnmmnn
(z)z88kkk8899zzk
(r)oot:x:0:0:root:/root:/bin/bash
[root@kvm ckh]#
[root@kvm ckh]# sed -r 's/([a-z])/(\1)/g' 1.txt
99(a)(a)(a)99(b)(b)(b)
(b)(b)(b)99(c)(c)(c)
#
  (a)(b)(c)

(c)(c)(c)(d)(d)(d)

(d)99(d)(d)(e)99(e)(e)
(e)(e)(e)88(f)(f)(f)
(m)(m)(n)(n)(m)(m)(n)(n)
(z)(z)88(k)(k)(k)8899(z)(z)(k)
(r)(o)(o)(t):(x):0:0:(r)(o)(o)(t):/(r)(o)(o)(t):/(b)(i)(n)/(b)(a)(s)(h)
[root@kvm ckh]# sed -r 's/([a-z])/(\1)/2' 1.txt
99a(a)a99bbb
b(b)b99ccc
#
  a(b)c

c(c)cddd

d99(d)de99ee
e(e)e88fff
m(m)nnmmnn
z(z)88kkk8899zzk
r(o)ot:x:0:0:root:/root:/bin/bash
4.操作文件
# i:insert 插入到该行前面, 在指定的行之前插入一行对应文本
# a:append 插入到该行后面, 在指定的行之后插入一行对应文本
# c:change 替换, 替换指定的行

# 第一个 i 表示修改源文件, 2i 表示在第2行插入 i:insert 插入, 在指定的行之前插入一行对应文本
[root@kvm ckh]# cat 1.txt
aaa
bbb
ccc
ddd
[root@kvm ckh]#
[root@kvm ckh]# sed -i '2i 111' 1.txt
[root@kvm ckh]#
[root@kvm ckh]# cat 1.txt
aaa
111
bbb
ccc
ddd

# 不加 i 的三种用法
[root@kvm ckh]# cat 1.txt
aaa
bbb
ccc
ddd
[root@kvm ckh]# sed  '2i 111' 1.txt
aaa
111
bbb
ccc
ddd
[root@kvm ckh]#
[root@kvm ckh]# sed  '2a 111' 1.txt
aaa
bbb
111
ccc
ddd
[root@kvm ckh]# sed  '2c 111' 1.txt
aaa
111
ccc
ddd

# 操作文件
[root@kvm ckh]# cat 1.txt
aaa
bbb
ccc
ddd
[root@kvm ckh]#
[root@kvm ckh]# sed 's/^/XXX/' 1.txt
XXXaaa
XXXbbb
XXXccc
XXXddd
[root@kvm ckh]#
[root@kvm ckh]# sed 's/$/XXX/' 1.txt
aaaXXX
bbbXXX
cccXXX
dddXXX
[root@kvm ckh]#
[root@kvm ckh]# sed '2s/$/XXX/' 1.txt
aaa
bbbXXX
ccc
ddd
[root@kvm ckh]# sed '2,4s/$/XXX/' 1.txt
aaa
bbbXXX
cccXXX
dddXXX
5.读取文件
# r 读取文件
# 读取2.txt的内容到1.txt
[root@kvm ckh]# ls
1.txt  2.txt
[root@kvm ckh]# cat 1.txt
aaa
bbb
ccc
ddd
[root@kvm ckh]#
[root@kvm ckh]# cat 2.txt
111
222
333
444
[root@kvm ckh]#
[root@kvm ckh]# sed 'r 2.txt' 1.txt
aaa
111
222
333
444
bbb
111
222
333
444
ccc
111
222
333
444
ddd
111
222
333
444
[root@kvm ckh]# sed '1r 2.txt' 1.txt
aaa
111
222
333
444
bbb
ccc
ddd

# h 覆盖的复制
# H 追加的复制 (不会覆盖剪切板里面的东西,即剪切版里面的还行还在,换行+内容)
# g 覆盖的粘贴 (替换原来行内容)
# G 追加的粘贴  (在行后插入对应内容)
# 后面大写 => 追加
# 前面大写 => 覆盖追加
# 从后往前看, -i 的话,表示修改源文件
[root@kvm ckh]# cat 1.txt
aaa
bbb
ccc
ddd
[root@kvm ckh]# sed '2h;4g' 1.txt
aaa
bbb
ccc
bbb
[root@kvm ckh]# sed '2h;4G' 1.txt
aaa
bbb
ccc
ddd
bbb
[root@kvm ckh]# sed '2H;4g' 1.txt
aaa
bbb
ccc

bbb
[root@kvm ckh]# sed '2H;4G' 1.txt
aaa
bbb
ccc
ddd

bbb

# 注意 [^] 表示取反
[root@kvm ckh]# cat 1.txt
aaa
bbb
ccc
ddd
[root@kvm ckh]#
[root@kvm ckh]# sed -n '/^[c]/p' 1.txt
ccc
[root@kvm ckh]# sed -n '/[^c]/p' 1.txt
aaa
bbb
ddd
[root@kvm ckh]# sed -n '/[^ac]/p' 1.txt
bbb
ddd