sed 工具简介
- sed Stream EDitor, 行编辑器
- 工具特性:sed是一种流编辑器,对标准输出 或 文件进行逐行处理。
- 工作过程:将当前行储存至内存空间中,称作“模式空间”(pattern space)。在模式空间中对行进行编辑,将处理结果输出至屏幕。一般情况下,清空模式空间内容,然后读入下一行执行下一个循环,如此循环直至文本文件行尾。
- 功能:编辑一个或多个文件,简化对文件的反复操作,编写转换程序等
sed 工具基本用法
-
语法:
sed [option]... 'script' inputfile...
stdout|sed [option] “pattern command”
sed [option] “pattern command” file
-
选项:
- -n 不输出模式空间内容到屏幕,即不自动打印,
- -e 多点编辑
- -f /PATH/SCRIPT_FILE 从指定文件中读取编辑脚本
- -r 支持使用扩展正则表达式
- -i 文件原处编辑
- -i.bak 备份文件(后缀 .bak)并原处编辑
选项 option
1i love python
2I love PYTHON
3golang is a very good language
1sed '2p' sed.txt //打印第二行 默认输出模式空间内容
2
3
4结果:
5i love python
6I love PYTHON
7I love PYTHON
8golang is a very good language
-n 不输出模式空间内容到屏幕
1sed -n '2p' sed.txt //-n 不输出模式空间内容到屏幕
2结果:
3I love PYTHON
1sed -n '/python/p' sed.txt //匹配含python行并打印
2结果:
3i love python
-e 多点
1sed -n -e '/python/p' -e '/PYTHON/p' sed.txt // 多点
2结果:
3i love python
4I love PYTHON
-f 指定匹配脚本
1vim edit.sed
2内容如下 /python/p
3
4sed -n -f edit.sed sed.txt //-f 指定匹配脚本文件
5结果:
6i love python
-r 使用扩展正则表达式
1sed -n -r '/python|PYTHON/p' sed.txt //-r 使用扩展正则表达式
2结果
3i love python
4I love PYTHON
编辑 -i
1sed.txt内容如下:
2i love love python
3I love PYTHON
4GOLANG IS AS good language
5
6
7sed -n 's/love/like/gp' sed.txt //g 每一行全部匹配, 不加g。最多匹配一次
8结果
9i like like python
10I like PYTHON
‘script’
‘script’描述对文本的地址定界和编辑命令
pattern
匹配模式 | 含义 |
---|---|
10command | 匹配到第10行 |
10,20command | 匹配从第10行开始,到第20行结束 |
10,+5command | 匹配从第10行开始,到第15行结束 |
/pattern1/command | 匹配到pattern1的行 |
/pattern1/,/pattern2/command | 匹配到pattern1的行开始,到匹配到pattern2的行结束 |
/pattern1/,10command | 匹配到pattern1的行开始,到第10行结束 |
- (1)不给地址:代表全文处理
- (2)单地址:
- #:指定第#行
- /pattern/:匹配模式描述的每一行
- (3)地址范围
- m,n:从第m行到第n行
- m,+n:从第m行到第(m+n)行
- /pat1/,/pat2/:从匹配pat1的行到匹配pat2的行
- m,/pat1/:从第m行到匹配pat1的行
- (4)步进 ~
- 1~2:从1开始,每次步进2,即1,3,5,7···奇数列
- 2~2:从2开始,每次步进2,即2,4,6,8···偶数列
编辑命令
类别 | 编辑命令 | 含义 |
---|---|---|
查询 | p | 打印 |
增加 | a | 行后追加 |
i | 行前追加 | |
r | 外部文件读入,行后追加 | |
w | 匹配行写入外部文件 | |
删除 | d | 删除 |
修改 | s/old/new | 将行内第一个old替换为new |
s/old/new/g | 将行内全部old替换为new | |
s/old/new/2g | 将行内前2个old替换为new | |
s/old/new/ig | 将行内全部old替换为new ,忽略大小写 |
1d //删除模式空间匹配的行,并立即启用下一轮循环
2p //打印当前模式空间内容,追加到默认输出之后
3a[\]text //在指定行后面追加文本,支持使用\n实现多行追加
4i[\]text //在行前面插入文本
5c[\]text //替换行为单行或多行文本
6w /path/somefile //保存模式匹配的行至指定文件
7r /path/somefile //读取指定文件的文本至模式空间中匹配到的行后
8= //为模式空间中的行打印行号
9! //模式空间中匹配行取反处理
行后追加
1sed -i '/python/a i hat python' sed.txt
2
3i love love python
4I love PYTHON
5GOLANG IS AS good language
6变为:
7i love love python
8i hat python
9I love PYTHON
10GOLANG IS AS good language
1行前追加
2sed -i '/python/i i hat python' sed.txt
外部文件读入,行后追加
1$sed -i '/python/r r.txt' sed.txt
2内容如下
3i love love python
4I love PYTHON
5GOLANG IS AS good language
6
7修改后
8i love love python
9aaaaa
10bbbb
11I love PYTHON
12GOLANG IS AS good language
匹配行写到外部文件
1sed -n '/python/w /tmp/1.txt' sed.txt #将含有python的行, 写到/tmp/1.txt 下
查找替换
s/regexp/replacement/修饰符
替代内容 replacement:
可以使用`&`符号指代匹配regexp表达式的内容,可也以出现`\1, \2`等正则表达式后项引用
修饰符:
- g:全局替换
- p :显示替换成功的行
- w /path/somefile:将替换成功的行保存至文件中
支持s@@@,s###等格式代替/
号,当查找和替换内容描述中有/
符号为避免使用过多转义字符时使用
实验
1sed '2p' /etc/passwd //打印/etc/passwd文件全部行,第2行重复打印一次
2sed -n '2p' /etc/passwd //只打印/etc/passwd文件第2行
3sed -n '1,4p' /etc/passwd //打印/etc/passwd文件第1-4行
4sed -n '/root/p' /etc/passwd //打印/etc/passwd文件包含root的行
5sed -n '2,/root/p' /etc/passwd从2行开始 //打印/etc/passwd文件第2行到包含root的行
6sed -n '/^$/=' /etc/bashrc' //显示/etc/bash_rc文件空行行号
7sed -n -e '/^$/p' -e '/^$/=' /etc/bashrc //打印/etc/bashrc文件空行并显示空行行号
8sed '/root/a\superman' /etc/passwd //在/etc/passwd文件root行后添加superman行
9sed '/root/i\superman' /etc/passwd //在/etc/passwd文件root行前添加superman行
10sed '/root/c\superman' /etc/passwd //在/etc/passwd文件root行替换为superman行
11sed '/^$/d' /etc/bashrc //删除/etc/bashrc文件空行
12sed '1,10d' /etc/bashrc //删除/etc/bashrc文件第1-10行
13sed 's/ftp/vsftpd/g' /etc/passwd //将/etc/passwd文件中的ftp全部替换为vsftpd
14sed -n 's/root/&superman/pg' /etc/passwd //将/etc/passwd文件中的root后添加superman并显示修改的行
15sed -n 's/root/superman&/pg' /etc/passwd //将/etc/passwd文件中的root前添加superman并显示修改的行
16sed -i '1d' file_name #删除第一行
-
a append
passwd文件第10行后 追加 append line behind
1sed -i '10a append line behind' passwd
第10行到20行追加 append line behind
1sed -i '10,20a append line behind' passwd
-
i passwd文件匹配到以yarn开头的行,在匹配行前追加append line before
1sed -i '/^yarn/i append line before' passwd
-
r
将/etc/fatab文件 的内容追加到passwd文件第20行后
1sed -i '20r /etc/fatab' passwd
将/etc/fatab文件到内容追加到passwd文件匹配/bin/bash 行后面
1sed -i '/\/bin\/bash/r /etc/fatab' passwd
-
w
将passwd文件匹配到/bin/bash的行追加到 /tmp/sed.txt
1sed -i '/\/bin\/bash/w /tmp/sed.txt' passwd
将passwd文件从第10行开始,到匹配hdfs开头的所有行内容追加到/tmp/sed-1.txt
1sed -i '10,/^hdfs/w /tmp/sed-1.txt' passwd
sed 工具高级用法
- 保持空间(hold space):一段内存空间,可以从模式空间读数据也可向模式空间写数据,为sed工具提供了更加灵活的使用方法。
- 选项
1 P //打印模式空间开端至第一个换行符内容,并追加到默认输出之前 2 h //把模式空间中的内容覆盖至保持空间中 3 H //把模式空间中的内容追加至保持空间中 4 g //从保持空间取出数据覆盖至模式空间 5 G //从保持空间取出内容追加至模式空间 6 x //把模式空间中的内容与保持空间中的内容进行互换 7 n //读取匹配到的行的下一行覆盖至模式空间 8 N //读取匹配到的行的下一行追加至模式空间 9 d //删除模式空间中的行 10 D //如果模式空间包含换行符,则删除模式空间开端至第一个换行符内容,重新启动循环但不会读取新的输入行。 11 如果模式空间不包含换行符,则会像发出d命令那样启动正常的新循环
- 实验
num 是一个文本文件
1sed -n 'n;p' num //打印偶数行
2sed '1!G;h;$!d' num //倒序输出行
3sed 'N;D' num //打印最后一行
4sed '$!N;$!D' num //打印最后两行
5sed '$!d' num //打印最后一行
6sed 'G' num //每一行后添加一行空行
7sed 'g' num //将每一行都清空为空行
8sed '/^$/d;G' num //所有空行删除,所有非空行之间添加一行空行
9sed 'n;d' num //打印奇数行
10sed -n '1!G;h;$p' num //倒序输出行
练习
1sed 's/{admin_branch}//g' ./.env.testing > .env //替换{admin_branch}为空
2sed -i "s/root/$abc/g" filename //直接替换root 为$abc变量 ,i直接编辑
3sed -i 'd' filename //全局删除,清空文件
4sed -n 's/shutdown/root/gp' passwd.bak //打印 shutdown 替换为root 的行,全局替换
5sed -n 's/shutdown/root/p' passwd.bak //打印 shutdown 替换为root 的行,当前行替换一次
6sed -n '1,10s/shutdown/root/gp' passwd.bak //1到10行替换shutdown为root
7sed '2r /etc/issue' /etc/fstab //第二行后面添加 /etc/issue 中的内容
8 sed '1,2d' /etc/fstab //删除第一,二行
9sed '/shutdown/d' passwd.bak //删除包含shutdown行
10sed '1+2d' /etc/fstab //删除 第一行 ,2,3行 删除3行
11sed '1d' /etc/fstab //删除1行
12
13
14& :引用模式匹配整个串
15sed.txt 内容如下:
161.hello ,like
172.hi,my love
18 sed 's#l..e#&r#g' sed.txt //将like 替换为 liker love替换为lover
19 sed 's#\(l..e\)#\1r#g' sed.txt //效果同上
20 history | sed 's#[[:space:]]##g' //去掉空格
21
221.删除 /etc/grub.conf 文件中行首的空白符
23 sed -r 's@^[[:space:]]+@@g' /etc/grub.conf
242.替换/etc/inittab文件中“id:3:initdefault:”一行中的数字为5
25sed 's@\(id:\)[0-9]\(:initdefault\)@\15\2@g' /etc/inittab
263.删除/etc/inittab 文件中的空白行
27sed '/^$/d' /etc/inittab
284.删除/etc/inittab 文件中开头的#号
29sed 's@^#@@' /etc/inittab
305.删除某文件中开头的#号 及后面的空白字符,但要求#号后门必须有空白字符;
31sed -r 's@^#[[:space:]]+@@' /etc/inittab
326.取出一个文件路径的目录名称;
33echo "/etc/rc.d/" | sed -r 's@^/.*/([^/]+)/?@\1@g' //rc.d
案例:统计mysql配置 各个段 配置项数量
1#!/bin/bash
2
3
4FILE_NAME=/etc/my.cnf
5
6
7function get_all_segments()
8{
9
10 echo "`sed -n '/\[.*\]/p' $FILE_NAME | sed -e 's/\[//g' -e 's/\]//g'`"
11}
12
13
14function count_segment()
15{
16 res="`sed -n "/\[$1\]/,/\[.*\]/p" /etc/my.cnf | grep -v '\[.*\]' |grep -v '^$'`"
17 index=0
18 for item in $res
19 do
20 index=$(($index + 1))
21 done
22 echo $index
23}
24
25
26for seg in `get_all_segments`;do
27 count=`count_segment $seg`
28
29 echo "配置项: $seg, 配置数量:$count"
30done
工作中的使用
给文件每行内容增加""
1sed -i.bak 's/.*/&",/' 1.txt
2sed -i.bak 's/.*/"&/' 1.txt
nginx 端口替换
1sed -i "s/:$1/:$2/" $nginx_conf_path
删除注释 和空行
1sed -i '/^$/d;/[:blank:]*#/d' nginx.conf