sed 工具简介

  • sed Stream EDitor, 行编辑器
  • 工具特性:sed是一种流编辑器,对标准输出 或 文件进行逐行处理。
  • 工作过程:将当前行储存至内存空间中,称作“模式空间”(pattern space)。在模式空间中对行进行编辑,将处理结果输出至屏幕。一般情况下,清空模式空间内容,然后读入下一行执行下一个循环,如此循环直至文本文件行尾。
  • 功能:编辑一个或多个文件,简化对文件的反复操作,编写转换程序等

sed 工具基本用法

  1. 语法:sed [option]... 'script' inputfile...

    stdout|sed [option] “pattern command”

    sed [option] “pattern command” file

  2. 选项:

  • -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  #删除第一行
  1. 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
    
  2. i passwd文件匹配到以yarn开头的行,在匹配行前追加append line before

    1sed -i '/^yarn/i append line before' passwd
    
  3. r

    将/etc/fatab文件 的内容追加到passwd文件第20行后

    1sed -i '20r /etc/fatab' passwd
    

    将/etc/fatab文件到内容追加到passwd文件匹配/bin/bash 行后面

    1sed -i '/\/bin\/bash/r /etc/fatab' passwd
    
  4. 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