本文同时发表在https://github.com/zhangyachen/zhangyachen.github.io/issues/32
记录下sed编译器的常见使用方法。
sed编辑器基于输入到命令行的或者是存储在文本文件中的命令来处理数据流中的数据。每次从输入中读取一行,用编辑器命令匹配数据,修改数据,输出到STDOUT。在流编辑器将所有命令与一行数据匹配之后,它会读取下一行数据并重复此过程。
替换
s/pattern/replacement/flags
关于flags:
- 数字:新文本替换第几处模式的地方。
- g:新文本会替换所有已有文本出现的地方。
- p:原来行的内容打印出来。
- w file:替换的结果写到文件中。
其中:-n和p一起使用,只会输出被substitute命令修改过的行
$ echo -e "This is test test
This is no" | sed -n 's/test/no/p'
This is no test
使用地址
默认,sed使用的命令会作用于所有行,使用行寻址使命令作用于特定的行。
两种方式:
- 行的数字范围
- 文本模式过滤出某行
[address]command
或者
address {
command1
command2
command3
}
数字方式
$ echo -e "one 1
two 1
three 1" | sed "2,$ s/1/2/"
one 1
two 2
three 2
(代表到最后一行,)和s之间有空格。
文本模式
/pattern/command
pattern
可以为正则表达式。
$ echo -e "one 123
two 456
three 789" | sed "/one/s/123/number/"
one number
two 456
three 789
组合命令
$ echo -e "one 123
two 456
three 789" | sed "2{
s/two/hehe/
s/456/444/
}"
one 123
hehe 444
three 789
或者:
$ echo -e "one 123
two 456
three 789" | sed "2{s/two/hehe/;s/456/444/}"
one 123
hehe 444
three 789
删除行
上面的两种方法均适用。
$ echo -e "one
two
three
four" | sed "/two/d"
one
three
four
使用两个文本模式删除某个范围内的行
$ echo -e "one
two
three
four" | sed "/one/,/three/d"
four
插入和附加文本
- 命令i在指定行之前插入
- 命令a在指定行之后插入
sed '[address]command
new line'
$ echo -e "one
two
three
four" | sed "$ afive"
one
two
three
four
five
修改行
$ echo -e "one
two
three
four" | sed "3cchange"
one
two
change
four
使用区间:
$ echo -e "one
two
three
four" | sed "1,2cchange"
change
three
four
sed会用这一行文本替换这两行,而不是逐一修改。
转换命令
转换命令是唯一可以处理单个字符的sed编辑器命令。
[address]y/inchars/outchars
将inchars和outchars进行一对一映射,如果长度不同,会产生一条错误消息。
转换命令是全局命令,会自动替换文本行中找到的指定字符的所有实例。
$ echo -e "1
2
3
4" | sed "y/123/789/"
7
8
9
4
回顾打印
- p命令用来打印文本行
- =命令用来打印行号
- l命令用来列出行
打印行
$ echo -e "one
two
three
four" | sed -n '3{
p
s/three/substitude/p
}'
three
substitude
同时显示原来的和新的行文本。
打印行号
$ echo -e "one
two
three
four" | sed -n '3{
=
p
}'
3
three
列出行
l允许打印数据流中的文本和不可打印的ASCI字符。任何不可打印的字符都用他们的八进制前加一个反斜线或者标准C命名法。
$ echo -e "one
two
three
four" | sed -n 'l'
one$
two$
three$
four$
sed和文件一起工作
向文件写入
[address]w filename
$ echo -e "one
two
three
four" | sed "1,2w data"
one
two
three
four
$ cat data
one
two
从文件读取数据
[address]r filename
不能对读取命令使用地址区间,而只能使用单独一个行号或者文本模式地址,sed会将文件中的文本插入到地址之后。
$ cat data
one
two
$ echo -e "one
two
three
four" | sed "3r data"
one
two
three
one
two
four
可以和删除命令一起使用来用另一个文件的数据替换文件中的占位文本。
$ cat data
Would the following people:
LIST
please report to the office
$ sed '/LIST/{
r list
d
}' data
Would the following people:
Zhangyachen
please report to the office
保持空间
模式空间是一块活动缓冲区,在sed编译器执行命令时它会保存sed编译器要检验的文本。
sed编辑器还利用了另一块缓冲区域,称作保持空间。你可以在处理模式空间中其他行是用保持空间来临时保存一些行。
命令 | 描述 |
---|---|
h | 将模式空间复制到保持空间 |
H | 将模式空间附加到保持空间 |
g | 将保持空间复制到模式空间 |
G | 将保持空间附加到模式空间 |
x | 交换两个空间的内容 |
next命令
单行next命令
小写的n命令会告诉sed编辑器移动到数据流中的下一文本行,而不用重新回到命令的最开始再执行一遍。
删除第一行之后的空白。
$ cat data
one
two
three
$ sed '/one/{
> n
> d
> }' data
one
two
three
合并文本行
多行版本的next命令N会将下一文本加到已在模式空间中的文本上。将两个文本行合并到同一模式空间,文本行仍然用换行符分隔,但是sed编辑器现在会将两行文本当做一行来处理。
待续。。。