sed常用语法

使用sed命令,可以对输入或输入文件的行进行筛选,替换,修改和打印等操作,并且可以将修改结果保存到源文件中。

sed命令语法:
sed [-nefri] ‘command’ file

参数说明
-n去掉缺省输出,缺省输出中包含sed命令读取的所有行,除替换和删除操作外一般会加上这个参数
-i将修改操作应用到源文件上,否则操作更改的内容只是显示到屏幕
-e允许对一行进行多次编辑
-r使用扩展的正则表达式
-f从文件中读取sed操作命令
命令说明
d删除行
p打印行
r读取文件
s替换字符串
a\在当前行后插入
i\在当前行前插入
c\修改当前行

1.匹配打印行

1)打印指定的行

#打印第1到第3行
sed -n '1,3p' /etc/passwd
root:x:0:0:root:/root:/bin/bash
bin:x:1:1:bin:/bin:/sbin/nologin
daemon:x:2:2:daemon:/sbin:/sbin/nologin

#打印最后一行
sed -n '$p' /etc/passwd
grid:x:501:501::/home/grid:/bin/bash

2)打印匹配样式的行

#打印含有字符串swap的行
sed -n '/swap/p' /etc/fstab
/dev/mapper/rhel-swap   swap                    swap    defaults        0 0

#打印匹配字符串oracle开始到最后一行
sed -n '/oracle/,$p' /etc/passwd
oracle:x:502:501:oracle:/home/oracle:/bin/bash
nscd:x:28:28:NSCD Daemon:/:/sbin/nologin
grid:x:501:501::/home/grid:/bin/bash

#打印注释行
sed -n '/^ *#/p' /etc/fstab
#
# /etc/fstab
# Created by anaconda on Mon Sep 13 11:39:56 2021
#
# Accessible filesystems, by reference, are maintained under '/dev/disk'
# See man pages fstab(5), findfs(8), mount(8) and/or blkid(8) for more info
#

#打印非注释行
sed -n '/^[^ *#]/p' /etc/fstab
/dev/mapper/rhel-root   /                       xfs     defaults        0 0
UUID=722b5e8f-6da6-4eba-abfe-8c6e7fddd67b /boot                   xfs     defaults        0 0
/dev/mapper/rhel-home   /u01                 xfs     defaults        0 0
/dev/mapper/rhel-swap   swap                    swap    defaults        0 0
tmpfs   /dev/shm        tmpfs   defaults,size=21G      0       0

#使用外部变量打印两个日期之间的日志
date1='Sep 22'
date2='Sep 23'
sed -n '/'"$date1"'/{p;:1;n;:2;/'"$date2"'/{p;b1};N;b2}' messages-20210926

3)打印与匹配样式相反的行

#打印不包含swap字符串的行
sed -n '/swap/!p' /etc/fstab

#
# /etc/fstab
# Created by anaconda on Mon Sep 13 11:39:56 2021
#
# Accessible filesystems, by reference, are maintained under '/dev/disk'
# See man pages fstab(5), findfs(8), mount(8) and/or blkid(8) for more info
#
/dev/mapper/rhel-root   /                       xfs     defaults        0 0
UUID=722b5e8f-6da6-4eba-abfe-8c6e7fddd67b /boot                   xfs     defaults        0 0
/dev/mapper/rhel-home   /u01                 xfs     defaults        0 0
tmpfs   /dev/shm        tmpfs   defaults,size=21G      0       0

4)打印匹配样式的行的行号

sed -n '/oracle/=' /etc/group
71
73
75

2.替换文本

sed可以使用正则表达式regexp匹配文件,然后使用replacement字符串进行替换。

语法:
sed [address [,address]] s/regexp/replacement/[g p w r]

替换选项说明
g缺省情况下只替换每行中第一次出现的样式,使用g选项进行每行中所有的匹配样式
p在sed命令加上-n参数时,被替换的行不会输出到屏幕,加上p选项可以只打印被替换的行到标准输出
w file只将替换过的行输出到一个文件file
r file将文件file的内容添加到匹配到的行后
#原文件
grep c33 file
68 c33 c22
60 c2 c33
58 c33 c33
48 c33 c33

#替换行中第1次出现的字符串
sed 's/c33/d33/' file |grep d33
68 d33 c22
60 c2 d33
58 d33 c33
48 d33 c33

#替换行中第2次出现的字符串
sed 's/c33/d33/2' file 
012 a1
234 a2
029 a3
345 b1
066 b2
108 d1
498 d2
59 d3
58 c1
68 c33 c22
60 c2 c33
58 c33 d33
48 c33 d33

#替换行中所有出现的字符串
sed 's/c33/d33/g' file |grep d33
68 d33 c22
60 c2 d33
58 d33 d33
48 d33 d33

#将替换过的行输出到newfile
sed 's/c33/d33/g w newfile' file 
012 a1
234 a2
029 a3
345 b1
066 b2
108 d1
498 d2
59 d3
58 c1
68 d33 c22
60 c2 d33
58 d33 d33
48 d33 d33

more newfile
68 d33 c22
60 c2 d33
58 d33 d33
48 d33 d33


#替换第一次出现的行中的字符串
sed '0,/c33/ s/c33/d33/g' file   #0,/c33/ 指第0行到第1次匹配到的行的地址
012 a1
234 a2
029 a3
345 b1
066 b2
108 d1
498 d2
59 d3
58 c1
68 d33 c22
60 c2 c33
58 c33 c33
48 c33 c33

#在原字符串前加上新字符串
sed 's/c33/&d33/g' file 
012 a1
234 a2
029 a3
345 b1
066 b2
108 d1
498 d2
59 d3
58 c1
68 c33d33 c22
60 c2 c33d33
58 c33d33 c33d33
48 c33d33 c33d33

#替换文件末尾的空格
sed -i 's/ *$//' file

#注释参数
sed -i '/^parameter/s/^/#/' file

3.删除行

sed命令使用d子命令删除匹配的行。

# cat file3
east 100000 10000
north 120000 9000
northwest 30000 6000
northeast 20000 5000
west 50000 7000
south 80000 8000
southeast 30000 6000
southwest 20000 4000
center  25000   5000

#删除匹配字符串east的行
sed '/east/d' file3
north 120000 9000
northwest 30000 6000
west 50000 7000
south 80000 8000
southwest 20000 4000
center  25000   5000

#删除第1到3行
sed '1,3d' file3
northeast 20000 5000
west 50000 7000
south 80000 8000
southeast 30000 6000
southwest 20000 4000
center  25000   5000

#删除从匹配字符串root开始到字符串tcpdump结束的行
sed '/root/,/tcpdump/d' /etc/passwd
oracle:x:502:501:oracle:/home/oracle:/bin/bash
nscd:x:28:28:NSCD Daemon:/:/sbin/nologin
grid:x:501:501::/home/grid:/bin/bash

#删除包含1位,2位和3位数字的UID的行
awk -F: '{print $3}' /etc/passwd |sed -e '/^.$/d' -e '/^..$/d' -e '/^...$/d'

#删除匹配行及前后2行
cat file8
1 a
2 b
3 c
4 d
5 e
6 f
7 g
8 h
9 i
10 j

sed '/e/,+2d;:go;1,2!{P;$!N;D};N;bgo' file8
1 a
2 b
8 h
9 i
10 j

#迁移匹配行到文件尾部,H代表复制到剪贴板,G代表粘贴到指定行
sed '/e/{H;d};$G' file8
1 a
2 b
3 c
4 d
6 f
7 g
8 h
9 i
10 j

5 e

4.插入行

插入命令说明
a 或 a\在当前行后插入一行或多行。
i 或 i\在当前行之前插入文本。
#在匹配字符串f后插入#7-10行
sed '/f/a#7-10' file8
1 a
2 b
3 c
4 d
5 e
6 f
#7-10
7 g
8 h
9 i
10 j

#在匹配字符串f前插入行#line6
sed '/f/i#line6' file8
1 a
2 b
3 c
4 d
5 e
#line6
6 f
7 g
8 h
9 i
10 j

#在第3行前插入多行
sed '3i#line3\n#line4' file8
1 a
2 b
#line3
#line4
3 c
4 d
5 e
6 f
7 g
8 h
9 i
10 j

#获取含有字符串的行号,然后在行号前插入内容
linenumber=`sed -n '/f/=' file8`
sed ''"$linenumber"'i#line f' file8
1 a
2 b
3 c
4 d
5 e
#line f
6 f
7 g
8 h
9 i

5.替换行

sed命令使用c\子命令替换当前行中的文件 。

cat file5
50 60
70 80
90 100

sed '/70/c 30 40' file5
50 60
30 40
90 100

6.组匹配

在匹配字符串时使用圆括号( )将一组字符串的正则表达式包含起来,就可以在后面使用相应的数字来引用该组字符串。第1个标记的正则表达式在后面用\1来引用,第2个标记的正则表达式在后面使用\2来引用,以此类推。组匹配的方式一般用于在更改行中的部分字符串时使用。
*注:在使用-r参数指定使用正则表达式时匹配圆括号前不要加*

#更改字符串顺序
echo aaa BBB | sed  's/\([a-z]\+\) \([A-Z]\+\)/\2 \1/'
BBB aaa

cat /etc/fstab
#
# /etc/fstab
# Created by anaconda on Mon Sep 13 11:39:56 2021
#
# Accessible filesystems, by reference, are maintained under '/dev/disk'
# See man pages fstab(5), findfs(8), mount(8) and/or blkid(8) for more info
#
/dev/mapper/rhel-root   /                       xfs     defaults        0 0
UUID=722b5e8f-6da6-4eba-abfe-8c6e7fddd67b /boot                   xfs     defaults        0 0
/dev/mapper/rhel-home   /u01                 xfs     noatime        0 0
/dev/mapper/rhel-swap   swap                    swap    defaults        0 0
tmpfs   /dev/shm        tmpfs   defaults,size=18G      0 0

sed -i -r 's/(tmpfs\s+\S+\s+\S+\s+)\S+(\s+[0-9]+\s+[0-9]+)/\1defaults,size=21G\2/' /etc/fstab
cat /etc/fstab
#
# /etc/fstab
# Created by anaconda on Mon Sep 13 11:39:56 2021
#
# Accessible filesystems, by reference, are maintained under '/dev/disk'
# See man pages fstab(5), findfs(8), mount(8) and/or blkid(8) for more info
#
/dev/mapper/rhel-root   /                       xfs     defaults        0 0
UUID=722b5e8f-6da6-4eba-abfe-8c6e7fddd67b /boot                   xfs     defaults        0 0
/dev/mapper/rhel-home   /u01                 xfs     noatime        0 0
/dev/mapper/rhel-swap   swap                    swap    defaults        0 0
tmpfs   /dev/shm        tmpfs   defaults,size=21G      0 0

7.引用外部变量

在sed命令中,使用单引号加双引号‘“$var”’引用外部变量。

district="east"
sed -n '/'"$district"'/p' file3
east 100000 10000
northeast 20000 5000
southeast 30000 6000

8.多行匹配处理

使用“:a;N;$!ba;”可以将文件的所有行都读取到缓冲区,然后进行匹配替换,一般用于对整个文件的第n处进行替换时使用(默认情况下是对每行的第n个匹配字符串进行处理)。子命令的各项含义如下:
:a 创建1个标记a
N 读取下一行到模式空间
$!ba 如果不是最后一行则跳转到标记a处(如果只读取n行,则可以用n替代$!,即n!ba)

#替换文件的第2个匹配的字符串c33
sed -n ':a;N;$!ba;s/c33/d33/2p' file
012 a1
234 a2
029 a3
345 b1
066 b2
108 d1
498 d2
59 d3
58 c1
68 c33 c22
60 c2 d33
58 c33 c33
48 c33 c33

#替换文件的最后1个匹配的字符串c33
sed -n -r ':a;N;$!ba;s/(.*)c33/\1d33/p' file
012 a1
234 a2
029 a3
345 b1
066 b2
108 d1
498 d2
59 d3
58 c1
68 c33 c22
60 c2 c33
58 c33 c33
48 c33 d33
56 e33
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值