Linux--sed命令
2019-08-27 本文已影响0人
李小李的路
概述
- sed 是一种新型的,非交互式的编辑器。它能执行与编辑器 vi 和 ex 相同的编辑任务。sed 编辑器没有提供交互式使用方式,使用者只能在命令行输入编辑命令、指定文件名,然后在屏幕上查看输出。 sed 编辑器没有破坏性,它不会修改文件,除非使用 shell 重定向来保存输出结果。默认情况下,所有的输出行都被打印到屏幕上。
sed工作过程
- sed 编辑器逐行处理文件(或输入),并将输出结果发送到屏幕。 sed 的命令就是在 vi和 ed/ex 编辑器中见到的那些。 sed 把当前正在处理的行保存在一个临时缓存区中,这个缓存区称为模式空间或临时缓冲。sed 处理完模式空间中的行后(即在该行上执行 sed 命令后),就把改行发送到屏幕上(除非之前有命令删除这一行或取消打印操作)。 sed 每处理完输入文件的最后一行后, sed 便结束运行。 sed 把每一行都存在临时缓存区中,对这个副本进行编辑,所以不会修改或破坏源文件。
sed命令格式
sed 命令行格式为: sed [选项] ‘ command’ 输入文本
sed定位功能
Sed 命令在没有给定的位置时,默认会处理所有行;
Sed 支持一下几种地址类型:
1、 first~step
这两个单词的意思: first 指起始匹配行, step 指步长,例如: sed -n 2~5p 含义:从第二行开始匹配,隔 5 行匹配一次,即 2,7,12.......。
2、 符表示匹配最后一行。
3、 /REGEXP/
这个是表示匹配正则那一行,通过//之间的正则来匹配。
4、 \cREGEXPc
这个是表示匹配正则那一行,通过\c 和 c 之间的正则来匹配,c 可以是任一字符
5、 addr1, add2
定址 addr1, add2 决定用于对哪些行进行编辑。地址的形式可以是数字、正则表达式或二者的结合。如果没有指定地址, sed 将处理输入文件中的所有行。如果定址是一个数字,则这个数字代表行号,如果是逗号分隔的两个行号,那么需要处理的定址就是两行之间的范围(包括两行在内)。范围可以是数字,正则或二者组合。
6、 addr1, +N
从 addr1 这行到往下 N 行匹配,总共匹配 N+1 行
7、 addr1, ~N
Will match addr1 and the lines following addr1 until the next line whose input line number is a multiple of N.【没有看懂是什么意思】
sed常见命令参数
p==print
d:delete
=:打印匹配行的行号
-n 取消默认的完整输出,只要需要的
-e 允许多项编辑
-i 修改文件内容
-r 不需要转义
sed命令功能
命令 功能
a\ 在当前行后添加一行或多行。多行时除最后一行外,每行末尾需用“\”续行
c\ 用此符号后的新文本替换当前行中的文本。多行时除最后一行外,每行末尾需用"\"续行
i\ 在当前行之前插入文本。多行时除最后一行外,每行末尾需用"\"续行
d 删除行
h 把模式空间里的内容复制到暂存缓冲区
H 把模式空间里的内容追加到暂存缓冲区
g 把暂存缓冲区里的内容复制到模式空间,覆盖原有的内容
G 把暂存缓冲区的内容追加到模式空间里,追加在原有内容的后面
l 列出非打印字符
p 打印行
n 读入下一输入行,并从下一条命令而不是第一条命令开始对其的处理
q 结束或退出sed
r 从文件中读取输入行
! 对所选行以外的所有行应用命令
s 用一个字符串替换另一个
g 在行内进行全局替换
w 将所选的行写入文件
x 交换暂存缓冲区与模式空间的内容
y 将字符替换为另一字符(不能对正则表达式使用y命令)
sed常见案例
- 测试源文件 sed.log
hhh pts/1 192.168.25.1 Sat Jun 30 22:04 still logged in
reboot system boot 2.6.32-358.el6.i Sat Jun 30 22:04 - 22:43 (00:38)
omc pts/0 192.168.25.1 Sat Jun 30 20:16 - down (00:00)
reboot system boot 2.6.32-358.el6.i Sat Jun 30 19:38 - 20:16 (00:37)
root pts/1 192.168.25.1 Sat Jun 30 12:20 - down (00:55)
root pts/0 192.168.25.1 Sat Jun 30 11:53 - down (01:22)
reboot system boot 2.6.32-358.el6.i Sat Jun 30 11:52 - 13:15 (01:23)
root pts/0 192.168.25.1 Sat Jun 30 05:40 - down (02:51)
reboot system boot 2.6.32-358.el6.i Sat Jun 30 05:38 - 08:32 (02:54)
root pts/0 192.168.25.1 Fri Jun 29 21:01 - down (06:21)
wtmp begins Tue Jun 9 03:57:56 2015
- 1-只打印第三行
[liyahui@172 ~]$ sed -n "3p" sed.log
omc pts/0 192.168.25.1 Sat Jun 30 20:16 - down (00:00)
- 2-只查看文件的第3行到第9行
[liyahui@172 ~]$ sed -n "3,9p" sed.log
omc pts/0 192.168.25.1 Sat Jun 30 20:16 - down (00:00)
reboot system boot 2.6.32-358.el6.i Sat Jun 30 19:38 - 20:16 (00:37)
root pts/1 192.168.25.1 Sat Jun 30 12:20 - down (00:55)
root pts/0 192.168.25.1 Sat Jun 30 11:53 - down (01:22)
reboot system boot 2.6.32-358.el6.i Sat Jun 30 11:52 - 13:15 (01:23)
root pts/0 192.168.25.1 Sat Jun 30 05:40 - down (02:51)
reboot system boot 2.6.32-358.el6.i Sat Jun 30 05:38 - 08:32 (02:54)
- 3-过滤特定字符串,显示正行内容
[liyahui@172 ~]$ sed -n "/root/p" sed.log
root pts/1 192.168.25.1 Sat Jun 30 12:20 - down (00:55)
root pts/0 192.168.25.1 Sat Jun 30 11:53 - down (01:22)
root pts/0 192.168.25.1 Sat Jun 30 05:40 - down (02:51)
root pts/0 192.168.25.1 Fri Jun 29 21:01 - down (06:21)
- 4-显示包含"hhh"的行到包含"omc"的行之间的行
[liyahui@172 ~]$ sed -n "/hhh/,/omc/p" sed.log
ihhh pts/1 192.168.25.1 Sat Jun 30 22:04 still logged in
reboot system boot 2.6.32-358.el6.i Sat Jun 30 22:04 - 22:43 (00:38)
omc pts/0 192.168.25.1 Sat Jun 30 20:16 - down (00:00)
- 5-打印1-5行,并显示行号
[liyahui@172 ~]$ nl sed.log | sed -n "1,5p"
1 ihhh pts/1 192.168.25.1 Sat Jun 30 22:04 still logged in
2 reboot system boot 2.6.32-358.el6.i Sat Jun 30 22:04 - 22:43 (00:38)
3 omc pts/0 192.168.25.1 Sat Jun 30 20:16 - down (00:00)
4 reboot system boot 2.6.32-358.el6.i Sat Jun 30 19:38 - 20:16 (00:37)
5 root pts/1 192.168.25.1 Sat Jun 30 12:20 - down (00:55)
- 6-仅仅显示匹配字符串的行号
[liyahui@172 ~]$ sed -n "/root/p" sed.log
root pts/1 192.168.25.1 Sat Jun 30 12:20 - down (00:55)
root pts/0 192.168.25.1 Sat Jun 30 11:53 - down (01:22)
root pts/0 192.168.25.1 Sat Jun 30 05:40 - down (02:51)
root pts/0 192.168.25.1 Fri Jun 29 21:01 - down (06:21)
[liyahui@172 ~]$ sed -n "/root/=" sed.log
5
6
8
10
- 7-打印匹配行的内容和符号【相当于后面又根据关键词查询了一次】
[liyahui@172 ~]$ sed -n -e "/root/p" -e "/root/=" sed.log
root pts/1 192.168.25.1 Sat Jun 30 12:20 - down (00:55)
5
root pts/0 192.168.25.1 Sat Jun 30 11:53 - down (01:22)
6
root pts/0 192.168.25.1 Sat Jun 30 05:40 - down (02:51)
8
root pts/0 192.168.25.1 Fri Jun 29 21:01 - down (06:21)
10
- 8-用world 替换yum.log文件中的root【真实写入】
==>sed -i 's#hhh#HHHH#g' h.txt 与上同
s==search 查找并替换
g==global 全部替换
-i: implace
[liyahui@172 ~]$ head -5 sed.log
ihhh pts/1 192.168.25.1 Sat Jun 30 22:04 still logged in
reboot system boot 2.6.32-358.el6.i Sat Jun 30 22:04 - 22:43 (00:38)
omc pts/0 192.168.25.1 Sat Jun 30 20:16 - down (00:00)
reboot system boot 2.6.32-358.el6.i Sat Jun 30 19:38 - 20:16 (00:37)
world pts/1 192.168.25.1 Sat Jun 30 12:20 - down (00:55)
- 9-在文件第一行添加happy,文件结尾添加new year
sed -i -e '1i happy' -e '$a new year' yum.log 【真实写入文件】
[liyahui@172 ~]$ sed -e '1i happy' -e '$a new year' sed.log
happy
ihhh pts/1 192.168.25.1 Sat Jun 30 22:04 still logged in
reboot system boot 2.6.32-358.el6.i Sat Jun 30 22:04 - 22:43 (00:38)
omc pts/0 192.168.25.1 Sat Jun 30 20:16 - down (00:00)
reboot system boot 2.6.32-358.el6.i Sat Jun 30 19:38 - 20:16 (00:37)
world pts/1 192.168.25.1 Sat Jun 30 12:20 - down (00:55)
world pts/0 192.168.25.1 Sat Jun 30 11:53 - down (01:22)
reboot system boot 2.6.32-358.el6.i Sat Jun 30 11:52 - 13:15 (01:23)
world pts/0 192.168.25.1 Sat Jun 30 05:40 - down (02:51)
reboot system boot 2.6.32-358.el6.i Sat Jun 30 05:38 - 08:32 (02:54)
world pts/0 192.168.25.1 Fri Jun 29 21:01 - down (06:21)
wtmp begins Tue Jun 9 03:57:56 2015
new year
- 10-在文件第一行和第四行的每行下面添加hahaha
[liyahui@172 ~]$ sed "1,4i hahahaha" sed.log
hahahaha
ihhh pts/1 192.168.25.1 Sat Jun 30 22:04 still logged in
hahahaha
reboot system boot 2.6.32-358.el6.i Sat Jun 30 22:04 - 22:43 (00:38)
hahahaha
omc pts/0 192.168.25.1 Sat Jun 30 20:16 - down (00:00)
hahahaha
reboot system boot 2.6.32-358.el6.i Sat Jun 30 19:38 - 20:16 (00:37)
world pts/1 192.168.25.1 Sat Jun 30 12:20 - down (00:55)
world pts/0 192.168.25.1 Sat Jun 30 11:53 - down (01:22)
reboot system boot 2.6.32-358.el6.i Sat Jun 30 11:52 - 13:15 (01:23)
world pts/0 192.168.25.1 Sat Jun 30 05:40 - down (02:51)
reboot system boot 2.6.32-358.el6.i Sat Jun 30 05:38 - 08:32 (02:54)
world pts/0 192.168.25.1 Fri Jun 29 21:01 - down (06:21)
wtmp begins Tue Jun 9 03:57:56 2015
- 11-& 符号在sed命令中代表上次匹配的结果
[liyahui@172 ~]$ sed 's/world/hello_&/g' sed.log
ihhh pts/1 192.168.25.1 Sat Jun 30 22:04 still logged in
reboot system boot 2.6.32-358.el6.i Sat Jun 30 22:04 - 22:43 (00:38)
omc pts/0 192.168.25.1 Sat Jun 30 20:16 - down (00:00)
reboot system boot 2.6.32-358.el6.i Sat Jun 30 19:38 - 20:16 (00:37)
hello_world pts/1 192.168.25.1 Sat Jun 30 12:20 - down (00:55)
hello_world pts/0 192.168.25.1 Sat Jun 30 11:53 - down (01:22)
reboot system boot 2.6.32-358.el6.i Sat Jun 30 11:52 - 13:15 (01:23)
hello_world pts/0 192.168.25.1 Sat Jun 30 05:40 - down (02:51)
reboot system boot 2.6.32-358.el6.i Sat Jun 30 05:38 - 08:32 (02:54)
hello_world pts/0 192.168.25.1 Fri Jun 29 21:01 - down (06:21)
wtmp begins Tue Jun 9 03:57:56 2015
- 12-删除第3到第9行,只是不显示而已
[liyahui@172 ~]$ sed "3,9d" sed.log
- 13-删除包含"hhh"的行到包含"omc"的行之间的行
sed '/omc/,10d' sed.log
- 备注:范围可以用数字、正则表达式、或二者的组合表示
- 显示中5到10行里匹配root,把行内所有的root替换为FTL,并打印到屏幕上
sed '5,10 s/root/FTL/g' yum.log【仅显示用】
sed -i sed '5,10 s/root/FTL/g' yum.log【-i 会真正替换信息】
- 14--e是编辑命令,用于多个编辑任务
删除1到5行后,替换reboot为shutdown
sed -e '1,5d' -e '=' -e 's/reboot/shutdown/g' sed.log
[liyahui@172 ~]$ sed -e '1,5d' -e '=' -e 's/reboot/shutdown/g' sed.log
6
world pts/0 192.168.25.1 Sat Jun 30 11:53 - down (01:22)
7
shutdown system boot 2.6.32-358.el6.i Sat Jun 30 11:52 - 13:15 (01:23)
8
world pts/0 192.168.25.1 Sat Jun 30 05:40 - down (02:51)
9
shutdown system boot 2.6.32-358.el6.i Sat Jun 30 05:38 - 08:32 (02:54)
10
world pts/0 192.168.25.1 Fri Jun 29 21:01 - down (06:21)
11
12
- 15-打印3到6行的内容,并匹配reboot替换为shutdown
sed -n -e '3,6p' -e 's/reboot/shutdown/g' sed.log
- 16--r命令是读命令。sed使用该命令将一个文本文件中的内容加到当前文件的特定位置上
[liyahui@172 ~]$ sed '/world/ r /home/liyahui/test.txt' sed.log
ihhh pts/1 192.168.25.1 Sat Jun 30 22:04 still logged in
reboot system boot 2.6.32-358.el6.i Sat Jun 30 22:04 - 22:43 (00:38)
omc pts/0 192.168.25.1 Sat Jun 30 20:16 - down (00:00)
reboot system boot 2.6.32-358.el6.i Sat Jun 30 19:38 - 20:16 (00:37)
world pts/1 192.168.25.1 Sat Jun 30 12:20 - down (00:55)
######
world pts/0 192.168.25.1 Sat Jun 30 11:53 - down (01:22)
######
reboot system boot 2.6.32-358.el6.i Sat Jun 30 11:52 - 13:15 (01:23)
world pts/0 192.168.25.1 Sat Jun 30 05:40 - down (02:51)
######
reboot system boot 2.6.32-358.el6.i Sat Jun 30 05:38 - 08:32 (02:54)
world pts/0 192.168.25.1 Fri Jun 29 21:01 - down (06:21)
######
wtmp begins Tue Jun 9 03:57:56 2015
[liyahui@172 ~]$ cat test.txt
######
*17 -w是写入命令
[liyahui@172 ~]$ sed "/world/ w /home/liyahui/world.txt" sed.log
ihhh pts/1 192.168.25.1 Sat Jun 30 22:04 still logged in
reboot system boot 2.6.32-358.el6.i Sat Jun 30 22:04 - 22:43 (00:38)
omc pts/0 192.168.25.1 Sat Jun 30 20:16 - down (00:00)
reboot system boot 2.6.32-358.el6.i Sat Jun 30 19:38 - 20:16 (00:37)
world pts/1 192.168.25.1 Sat Jun 30 12:20 - down (00:55)
world pts/0 192.168.25.1 Sat Jun 30 11:53 - down (01:22)
reboot system boot 2.6.32-358.el6.i Sat Jun 30 11:52 - 13:15 (01:23)
world pts/0 192.168.25.1 Sat Jun 30 05:40 - down (02:51)
reboot system boot 2.6.32-358.el6.i Sat Jun 30 05:38 - 08:32 (02:54)
world pts/0 192.168.25.1 Fri Jun 29 21:01 - down (06:21)
wtmp begins Tue Jun 9 03:57:56 2015
[liyahui@172 ~]$ cat world.txt
world pts/1 192.168.25.1 Sat Jun 30 12:20 - down (00:55)
world pts/0 192.168.25.1 Sat Jun 30 11:53 - down (01:22)
world pts/0 192.168.25.1 Sat Jun 30 05:40 - down (02:51)
world pts/0 192.168.25.1 Fri Jun 29 21:01 - down (06:21)
- 18-sed的正则匹配
[liyahui@172 ~]$ ifconfig | sed -n "2p"
inet 172.25.1.20 netmask 255.255.255.0 broadcast 172.25.1.255
[liyahui@172 ~]$ ifconfig |sed -n '2p' | sed -r 's#.*r:(.*) B.*k:(.*)#\1 \2#g'
inet 172.25.1.20 netmask 255.255.255.0 broadcast 172.25.1.255
[liyahui@172 ~]$
(.*)表示匹配的项,之后可以用\1取出第一个括号内匹配的内容,\2取出第二个括号内匹配的内容
- 19-配合find使用
find . -name "*.txt" |xargs sed -i 's/hhhh/\hHHh/g'
find . -name "*.txt" |xargs sed -i 's#hhhh#hHHh#g'
find . -name "*.txt" -exec sed -i 's/hhhh/\hHHh/g' {} \;
find . -name "*.txt" |xargs cat
- 20-未完待续