shell_sed
目录
sed 作为一种非交互式编辑器,它使用预先设定好的编辑指令对输入的文本进行编辑,完成之后输出编辑结果。
- sed 从输入文件中读取内容,
每次处理一行内容,并把当前的一行内容存储在临时的缓冲区中
,称为模式空间
。- 接着
用 sed 命令处理缓存区中的内容
;处理完毕后,把缓存区的内容送往屏幕
;接着处理下一行
;这样不断重复,直到文件末尾,文件内容并没有改变,除非你使用重定向输出或指定了
i
参数
1. 正则表达式
.1. 基本正则表达式
.
,表示匹配任意一个字符,除了换行符,类似 Shell 通配符中的?
;*
,表示匹配字符有 0 个或多个;.*
,表示任意一个字符有 0 个或多个,也就是能匹配任意的字符;^
,表示行首
,也就是每一行的开始位置,^abc
匹配以 abc 开头的字符串;$
,表示行尾
,也就是每一行的结尾位置,}$
匹配以大括号结尾的字符串;{}
,表示重复字符的数量范围,{2}
,表示重复 2 次,{2,}
重复至少 2 次,{2,4}
重复 2-4 次;[]
,括号中可以包含表示字符集的表达式,使用方法大概如下几种- [a-z] : 表示匹配 小写字母
- [A-Z]:表示匹配大写字母
- [0-9]:表示匹配数组
- [^0-9]:表示匹配非数字类型字符
.2. 扩展正则表达式
?
:表示前置字符有 0 个或 1 个;+
:表示前置字符有 1 个或多个;|
:表示匹配其中的一项即可;()
:表示分组,(a|b)b
表示可以匹配 ab 或 bb 子串,且命令表达式中可以通过\1
、\2
来表示匹配的变量{}
:和基本正则中的大括号中意义相同,只不过使用时不用加 转义符号;
2. sed 基本语法
sed [选项] 'command' filename
-n
,表示安静模式。默认 sed 会把每行内容处理完毕后打印到屏幕上,加上选项后就不会输出到屏幕上。-e
,如果需要用 sed 对文本内容进行多种操作,则需要执行多条子命令来进行操作;-i
,默认 sed只会处理模式空间的副本内容,不会直接修改文件
,如果需要修改文件,就要指定-i
选项;-f
,如果命令操作比较多时,用-e
会有点力不从心,这时需要把多个子命令写入脚本文件,使用-f
选项指定执行该脚本;-r
:如果需要支持扩展正则表达式,那么需要添加-r
选项;
3. 定址
.1. 数字定址
# 只将第4行中hello替换为A
$ sed '4s/hello/A/g' file.txt
# 将第2-4行中hello替换为A
$ sed '2,4s/hello/A/g' file.txt
# 从第2行开始,往下数4行,也就是2-6行
$ sed '2,+4s/hello/A/g' file.txt
# 将最后1行中hello替换为A
$ sed '$s/hello/A/g' file.txt
# 除了第1行,其它行将hello替换为A
$ sed '1!s/hello/A/g' file.txt
.2. 正则定址
# 将匹配到hello的行执行删除操作,d 表示删除
$ sed '/hello/d' file.txt
# 删除空行,"^$" 表示空行
$ sed '/^$/d' file.txt
# 将匹配到以ts开头的行到以te开头的行之间所有行进行删除
$ sed '/^ts/,/^te/d' file.txt
.3. 数字定址和正则定址混用
# 匹配从第1行到ts开头的行,把匹配的行执行删除
$ sed '1,/^ts/d' file.txt
4. 基本功能
.1. 替换子命令 s
[address]s/pat/rep/flags
- 替换子命令基本用法
# 将每行的hello替换为HELLO,只替换匹配到的第一个(每行的第一个)
$ sed 's/hello/HELLO/' file.txt
# 将匹配到的hello全部替换为HELLO,g表示替换一行所有匹配到的
$ sed 's/hello/HELLO/g' file.txt
sed 's/123/hello/2' 1.txt #将每行中第二个匹配的123替换为hello
# 将第2次后匹配到的所有都替换
$ sed 's/hello/A/2g' file.txt
# 在行首加#号
$ sed 's/^/#/g' file.txt
# 在行尾加东西
$ sed 's/$/xxx/g' file.txt
- 正则表达式的简单使用
# 使用扩展正则表达式,结果为:A
$ echo "hello 123 world" | sed -r 's/[a-z]+ [0-9]+ [a-z]+/A/'
# <b>This</b> is what <span style="x">I</span> meant
# 要求:去掉上述html文件中的tags
$ sed 's/<[^>]*>//g' file.txt
- 多个匹配
# 将1-3行的my替换为your,且3行以后的This替换为That
$ sed '1,3s/my/your/g; 3,$s/This/That/g' my.txt
# 等价于
$ sed -e '1,3s/my/your/g' -e '3,$s/This/That/g' my.txt
- 使用匹配到的变量
# 将匹配到的字符串前后加双引号,结果为:My "name" chopin
# "&"表示匹配到的整个结果集
$ echo "My name chopin" | sed 's/name/"&"/'
# 如下命令,结果为:hello=world,"\1"和"\2"表示圆括号匹配到的值
$ echo "hello,123,world" | sed 's/\([^,]\),.*,\(.*\)/\1=\2/'
- 其它几个常见用法
# 只将修改匹配到行内容打印出来,-n关闭了模式空间的打印模式
$ sed -n 's/i/A/p' file.txt
# 替换是忽略大小写,将大小写i替换为A
$ sed -n 's/i/A/i' file.txt
# 将替换后的内容另存为一个文件
$ sed -n 's/i/A/w b.txt' file.txt
$ sed -n 's/i/A/' file.txt > b.txt
.2. 追加行子命令 a
- 子命令
a
表示在指定行下边插入指定的内容行;
# 将所有行下边都添加一行内容A
$ sed 'a A' file.txt
# 将文件中1-2行下边都添加一行内容A
$ sed '1,2a A' file.txt
sed '/123/a hello' 1.txt #向内容123后面添加hello,如果文件中有多行包括123,则每一行后面都会添加
.3. 插入行子命令 i
- 只不过是在指定行
上边插入指定的内容行
# 将文件中1-2行上边都添加一行内容A
$ sed '1,2i A'
.4. 替换行子命令 c
- 子命令
c
是表示把指定的行内容替换为自己需要的行内容
# 将文件所有行都分别替换为A
$ sed 'c A' file.txt
# 将文件中1-2行内容替换为A,注意:两行内容变成了一行A
$ sed '1,2c A' file.txt
# 将1-2行内容分别替换为A行内容
$ sed '1,2c A\nA' file.txt
.5. 删除行子命令 d
# 将文件中1-3行内容删除
$ sed '1,3d' file.txt
# 将文件中This开头的行内容删除
$ sed '/^This/d' file.txt
sed '1~2d' 1.txt #从第一行开始删除,每隔2行就删掉一行,即删除奇数行
sed '1,2!d' 1.txt #删除1~2之外的所有行
sed '/123/,$d' 1.txt #删除从匹配123的行到最后一行
sed '/123/,+1d' 1.txt #删除匹配123的行及其后面一行
sed '/^$/d' 1.txt #删除空行
sed '/123\|abc/!d' 1.txt #删除不匹配123或abc的行,/123\|abc/ 表示匹配123或abc ,!表示取反
.6. 设置行号子命令 =
# 将指定行上边显示行号
$ sed '1,2=' file.txt
# 可以将行号设置在行首
$ sed '=' file.txt | sed 'N;s/\n/\t/'
5. 案例
sed -r 's/(.)(.)(.*)$/\1\3/' file.txt # 删除文件每行的第二个字符
sed 's/[0-9]//g' file.txt #删除文件中所有的数字
sed -r 's/ +/\t/g' file.txt #用制表符替换文件中出现的所有空格
sed '/^$/d' file.txt #删除所有空白行