Sed用法

44 阅读7分钟

Sed

sed命令是利用脚本来处理文本文件。它可以依照脚本的指令来处理、编辑文本文件。主要用来自动编辑一个或多个文件、简化对文件的反复操作、编写转换程序等。

Sed的原理

  • 读入新的一行内容到缓存空间:
  • 从指定的操作指令中取出第一条指令,判断是否匹配pattern;
  • 如果不匹配,则忽略后续的编辑命令,回到第2步继续取出下一条指令;
  • 如果匹配,则针对缓存的行执行后续的编辑命令;完成后,回到第2步继续取出下一条指令;
  • 当所有指令都应用之后,输出缓存行的内容;回到第1步继续读入下一行内容;
  • 当所有行都处理完之后,结束;

命令格式

sed -e '操作' 文件1 文件2 
sed -n -e '操作' 文件1 文件2 
sed -f 脚本文件 文件1 文件2  
sed -i -e '操作' 文件1 文件2

执行多条命令的方法:

 sed -n -e '操作1' -e '操作2' 文件
 sed -n -e '操作1;操作2' 文件
 sed -e 'n{
 操作1
 操作2
 ......
 }' 文件1

Sed的选项

常用选项

选项作用
-e 或 --expression=表示用指定命令来处理输入的文本文件,只有一个操作命令时可省略,一般在执行多个操作命令使用
-f 或 --file=表示用指定的脚本文件来处理输入的文本文件
-h 或 --help显示帮助
-n、--quiet 或 silent禁止sed编辑器输出,但可以与p命令一起使用完成输出
-i直接修改目标文本文件

常用的操作符

选项含义
s替换,替换指定字符
d删除,删除选定的行
a添加,在当前行下面增加一行指定内容
i插入,在选定行上面插入一行指定内容
c替换,将选定行替换为指定内容
Y字符转换,转换前后的字符长度必须相同
p打印,如果同时指定行,表示打印指定行。如果不指定行,则表示打印所有内容,如果有非打印字符,则以ASCII 码输出,其通常与"-n"选项一起使用
=打印行号
i(小写L)打印数据流中的文本和不可打印的ABCII字符(比如结束符$,制表符\t)

sed增删改查

 查: p

 删: d

 改: s(字符串替换)、c(整行替换)、y(对应字符进行替换,效果类似tr命令)

 增: i(在行前插入内容)、a(在行后添加内容)、r(在行后读入文件的内容)
 
 复制粘贴:H(复制)、d(删除)、G(粘贴到指定行下方)

sed命令应用

sed 编辑器默认输出行内容,-n选项可以禁止输出。如果不加-n,使用p操作,那么每行内容会打印两次。

sed -e 'p':会打印两次

[root@localhost ~]# sed -e 'p' 3.txt
-e会打印两次
one
one
two
two
three
three
four
four
five
five
six
six
seven
seven
eight
eight
nine
nine
ten
ten

sed -n -e 'p':跳过显示过程,所以每行内容只会显示一次

[root@localhost ~]# sed -n -e 'p' 3.txt   
-n跳过显示过程,所以每行内容只会显示一次
one
two
three
four
five
six
seven
eight
nine
ten

sed -n '=' :打印行号

[root@localhost ~]# sed -n '=' 3.txt  
打印行号
1
2
3
4
5
6
7
8
9
10

sed -e '=':打印行号与内容

[root@localhost ~]# sed -e '=' 3.txt  
打印行号与内容
1
one
2
two
3
three
4
four
5
five
6
six
7
seven
8
eight
9
nine
10
ten
[root@localhost ~]# sed -n '=;p' 3.txt  
括号里面加上一个分号,就可以实现多命令
1
one
2
two
3
three
4
four
5
five
6
six
7
seven
8
eight
9
nine
10
ten

sed -n 'l': l 代表结束符$ ,制表符\t

[root@localhost ~]# sed -n 'l' 3.txt
l代表结束符$   ,制表符\t
one$
two$
three$
four$
five$
six$
seven$
eight$
nine$
ten$

执行多命令的方法

#方法一  
sed -n -e '=' -e 'p' file.txt  

#方法二
sed -n -e '=;p' file.txt  

#方法三:换行操作  
sed -n'  
^=
^p  
^' file.txt

用数字来显示行

操作含义
'1p'打印第一行
'$p'打印最后一行
'1,3p'打印连续行,打印第一行到第三行
'6,$p打印第六行到最后一行
'1,+3p'打印第一行加后面三行(即打印第一到第四行)
'5q'打印前五行后退出
'p;n'打印奇数行
'n;p'打印偶数行
'2,${n;p}'从第三行打印一直到奇数行

单行打印

[root@localhost ~]# sed -n '1p' 3.txt 
只显示第一行
one
[root@localhost ~]# sed -n '3p' 3.txt  
只显示第三行
three

多行打印

[root@localhost ~]# sed -n '1,3p' 3.txt
显示第一行到第三行
one
two
three
[root@localhost ~]# sed -n '6,$p' 3.txt  
显示第六行到最后一行
six
seven
eight
nine
ten
[root@localhost ~]# sed -n '1,+3p' 3.txt 
打印第一行以及它之后的连续三行内容(如同1-4行一样)
one
two
three
four

打印五行的方法

[root@localhost ~]# sed '5q' 3.txt  
打印五行后退出(相当于1-5行)
one
two
three
four
five

[root@localhost ~]# sed -n '1,5p' 3.txt
one
two
three
four
five

[root@localhost ~]# sed -n '1,+4p' 3.txt
one
two
three
four
five

打印奇数,偶数行

sed -n 'p;n':读取下一行,奇数

sed -n 'n;p':偶数

[root@localhost ~]# sed -n 'p;n' 3.txt  
P打印输出并,n读取下一行内容(循环所以会输出奇数)
one
three
five
seven
nine

[root@localhost ~]# sed -n 'n;p' 3.txt
two
four
six
eight
ten

sed -n '2,${n;p}' //从第三行打印一直到奇数行

[root@localhost ~]# sed -n '2,${n;p}' 3.txt 
从第三行打印一直到奇数行
three
five
seven
nine

通过字符串来过去文本

打印包含six字符串的行内容

[root@localhost ~]# sed -n '/six/p' 3.txt 
打印包含six字符串的行内容
six

打印包含root的行内容

[root@localhost ~]# grep 'root' /etc/passwd
root:x:0:0:root:/root:/bin/bash
operator:x:11:0:operator:/root:/sbin/nologin

[root@localhost ~]# sed -n '/root/p' /etc/passwd 
打印包含root的行内容
root:x:0:0:root:/root:/bin/bash
operator:x:11:0:operator:/root:/sbin/nologin

运用正则表达式打印

运用正则表达式查看以root开头的行内容
[root@localhost ~]# sed -n '/^root/p' /etc/passwd
root:x:0:0:root:/root:/bin/bash

运用正则表达式查看以bash结尾的行内容
[root@localhost ~]# sed -n  '/bash$/p' /etc/passwd
root:x:0:0:root:/root:/bin/bash
w:x:1000:1000:w:/home/w:/bin/bash
wangwu:x:1001:1001::/home/wangwu:/bin/bash
shangsan:x:1002:1002::/home/shangsan:/bin/bash
zhuliu:x:1003:1003::/home/zhuliu:/bin/bash
laoba:x:1004:1004::/home/laoba:/bin/bash
laoliu:x:1005:1005::/home/laoliu:/bin/bash
liangliang:x:1006:1006::/home/liangliang:/bin/bash
jiujiu:x:1007:1007::/home/jiujiu:/bin/bash
baibai:x:1008:1008::/home/baibai:/bin/bash

-r与

[root@localhost ~]# sed -n '/mail|games/p' /etc/passwd   
要使用 | 必须要加上-r才能打印出来
[root@localhost ~]# sed -nr '/mail|games/p' /etc/passwd
mail:x:8:12:mail:/var/spool/mail:/sbin/nologin
games:x:12:100:games:/usr/games:/sbin/nologin

[root@localhost ~]# sed -n '/mail|games/p' /etc/passwd 
不想加-r的话可以使用\来打印
mail:x:8:12:mail:/var/spool/mail:/sbin/nologin
games:x:12:100:games:/usr/games:/sbin/nologin
[root@localhost ~]# sed -n '/mail|games/p' /etc/passwd
mail:x:8:12:mail:/var/spool/mail:/sbin/nologin
games:x:12:100:games:/usr/games:/sbin/nologin
[root@localhost ~]# sed -n '/nobody/=' /etc/passwd
13
35



[root@localhost ~]# sed -n '2,/nobody/p' /etc/passwd   
从第二行开始一直到第一个包含nobody的行打印出来(相当于就是从第二行到十三行)
bin:x:1:1:bin:/bin:/sbin/nologin
daemon:x:2:2:daemon:/sbin:/sbin/nologin
adm:x:3:4:adm:/var/adm:/sbin/nologin
lp:x:4:7:lp:/var/spool/lpd:/sbin/nologin
sync:x:5:0:sync:/sbin:/bin/sync
shutdown:x:6:0:shutdown:/sbin:/sbin/shutdown
halt:x:7:0:halt:/sbin:/sbin/halt
mail:x:8:12:mail:/var/spool/mail:/sbin/nologin
operator:x:11:0:operator:/root:/sbin/nologin
games:x:12:100:games:/usr/games:/sbin/nologin
ftp:x:14:50:FTP User:/var/ftp:/sbin/nologin
nobody:x:99:99:Nobody:/:/sbin/nologin
[root@localhost ~]# sed -n '2,/nobody/=' /etc/passwd
2
3
4
5
6
7
8
9
10
11
12
13

[root@localhost ~]# sed -rn '/r.{1,}t/p' /etc/passwd 
显示包含r和t中间有任意字符的打印出来
root:x:0:0:root:/root:/bin/bash
operator:x:11:0:operator:/root:/sbin/nologin
ftp:x:14:50:FTP User:/var/ftp:/sbin/nologin
systemd-network:x:192:192:systemd Network Management:/:/sbin/nologin
polkitd:x:999:997:User for polkitd:/:/sbin/nologin
abrt:x:173:173::/etc/abrt:/sbin/nologin
libstoragemgmt:x:998:995:daemon account for libstoragemgmt:/var/run/lsm:/sbin/nologin
saslauth:x:996:76:Saslauthd user:/run/saslauthd:/sbin/nologin
setroubleshoot:x:995:993::/var/lib/setroubleshoot:/sbin/nologin
rtkit:x:172:172:RealtimeKit:/proc:/sbin/nologin
tss:x:59:59:Account used by the trousers package to sandbox the tcsd daemon:/dev/null:/sbin/nologin
gnome-initial-setup:x:991:986::/run/gnome-initial-setup/:/sbin/nologin
postfix:x:89:89::/var/spool/postfix:/sbin/nologin
sshd:x:74:74:Privilege-separated SSH:/var/empty/sshd:/sbin/nologin
apache:x:48:48:Apache:/usr/share/httpd:/sbin/nologin

sed删除行

dart
复制代码
[root@localhost ~]# sed 'd' 3.txt 
全部删除

[root@localhost ~]# sed '1d' 3.txt 
删除第一行
two
three
four
five
six
seven
eight
nine
ten

[root@localhost ~]# sed '$d' 3.txt 
删除最后一行
one
two
three
four
five
six
seven
eight
nine
[root@localhost ~]# sed '1,3d' 3.txt  
删除一到三行
four
five
six
seven
eight
nine
ten

[root@localhost ~]# sed '4,$d' 3.txt 
删除第四行到最后一行
one
two
three

sed '/^s/d':删除以s开头的行

[root@localhost ~]# sed '/^s/d' 3.txt  
删除以s开头的行
one
two
three
four
five
eight
nine
ten
[root@localhost ~]# sed '/en$/d' 3.txt  
删除以en结尾的行
one
two
three
four
five
six
eight
nine

!号取反

[root@localhost ~]# sed '/en$/!d' 3.txt 
除了以en结尾的都删除
seven
ten

删除空行的方法

[root@localhost ~]# grep -v "^$" 3.txt
one
two
three
four
five
six
seven
eigh
nine
ten


[root@localhost ~]# cat 3.txt |tr -s '\n'
one
two
three
four
five
six
seven
eigh
nine
ten


[root@localhost ~]# sed '/^$/d' 3.txt
one
two
three
four
five
six
seven
eigh
nine
ten


[root@localhost ~]# sed -n '/^$/!p' 3.txt  
反向删除
one
two
three
four
five
six
seven
eigh
nine
ten
[root@localhost ~]# sed '/2/,/5/d' 4.txt 
删除从第一个包含2的行到第一个包含5的行
1
5
444
555
1000
165
85
555
666
166
999
888

[root@localhost ~]# sed '/1/,/5/d' 4.txt 
从第一个位置打开删除功能,到第二个位置关闭删除功能
5
444
555
85
555
666

删除空行的三种方法:

  1. grep -v "^$" file.txt //过滤出非空行
  2. cat file.txt |tr -s "\n" //压缩换行符
  3. sed '/^$/d' file.txt //删除空行

sed替换

s:替换字符串

c:整行替换

y:字符替换,替换前后的字符串长度必须相同

替换字符串格式:

行范围 s/旧字符串/新字符串/替换标记  
#4种替换标记:
数字:表明新字符串将替换第几处匹配的地方
g:表面新字符串将会替换所有匹配的地方
p:打印与替换命令匹配的行,与-n一起使用
w 文件:将替换的结果写入文件中

操作

[root@localhost ~]# sed -n '/root/p' /etc/passwd 
查找包含root的行
root:x:0:0:root:/root:/bin/bash
operator:x:11:0:operator:/root:/sbin/nologin

[root@localhost ~]# sed -n 's/root/admin/p' /etc/passwd 
把root换成admin
admin:x:0:0:root:/root:/bin/bash
operator:x:11:0:operator:/admin:/sbin/nologin
[root@localhost ~]# sed -n '/^root/ s/root/admin/p' /etc/passwd  
更换以root开头的行并把root替换成admin,默认只更换匹配到的第一行
admin:x:0:0:root:/root:/bin/bash

[root@localhost ~]# sed -n '/^root/ s/root/admin/2p' /etc/passwd 
替换第二个root
root:x:0:0:admin:/root:/bin/bash

[root@localhost ~]# sed -n '/^root/ s/root/admin/gp' /etc/passwd  
g是代表所有的
admin:x:0:0:admin:/admin:/bin/bash

[root@localhost ~]# sed -n '/^root/ s/root//gp' /etc/passwd
匹配包含root的行,将root替换成空格
:x:0:0::/:/bin/bash
[root@localhost ~]# sed '1 s/^/#/' 3.txt 
给行首加上注释符
#one
two
three
four
five
six
seven
eigh
nine
ten

[root@localhost ~]# sed '1,5 s/^/#/' 3.txt 
一到五行加上注释符号
#one
#two
#three
#four
#five
six
seven
eigh
nine
ten
[root@localhost ~]# sed '/^#f/ s/#//' 3.txt 
删除以#f开头的注释
#one
#one
#two
#two
#three
#three
four
four
five
five
six
seven
eigh
nine
ten

大小写的转换

[root@localhost ~]# echo abcdefgh | tr a-z A-Z
ABCDEFGH
sed -f  脚本文件
s/ [a-z] /\u& / g  小写转大写
s/ \b [ a-z]/\u& / g  首字母小写转大写
s/[A-zj/\l&/g   大写转小写