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
删除空行的三种方法:
- grep -v "^$" file.txt //过滤出非空行
- cat file.txt |tr -s "\n" //压缩换行符
- 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 大写转小写