前言
=====
sed 命令是 Linux 核心命令之一,熟悉 sed 命令可以让程序员在 Linux 环境下更加灵活的处理各种文本,做到事半功倍的效果,甚至再也不用打开文件逐行编辑。
笔者将个人对 sed 理解加以归纳整理,供大家学习借鉴,如果不当之处欢迎斧正。
基本格式
首先介绍下 sed 命令的基本格式,万变不离其宗
[address]command
其中 command
可以有多个,形如
[address]{
command
command
}
如果 address
为空,可直接省略花括号 {}
address
所谓 address 就是定义将 command[flags] 用在特定行上
如果 address 为空,则 sed 逐行执行 command
两种寻址方式
数字方式行寻址
我们可以简单的使用 1,2,3,4
等表示第几行,且 $
表示最后一行,比如
-
2
表示选中第二行数据 -
1,3
表示选中 1 ~ 3 行数据,闭区间 -
1,$
表示从第一行到最后一行,闭区间
文本模式匹配寻址
从数据内容出发,支持正则匹配找到对应行。假设有文本 text1 内容
This is first line
This is second line
This is third line
This is forth line
-
/third/
可以匹配到第三行 -
/f/
可以匹配第一行和第四行 -
/first/,/third/
可以匹配 1 ~ 3 行,闭区间 -
/^This is [a-z]\{4\} line$/
可以匹配1,3,4
行
前三个例子是文本模式匹配,最后一个例子是正则匹配,表示匹配 This is 和 line 之间有四个 a-z 组成的字母的行,对正则表达式不清楚的伙伴可以参考我之前发到文章「Linux-正则表达式」,对此做了详细的说明
反向寻址
在寻址后面加上 !
表明选取这段地址之外的行,比如
-
2,3!
表示选取除了第二行和第三行之外的所有行 -
/first/!
表示选取2,3,4
行
command
s 替换
替换命令是最常见之一,使用格式为
s/pattern/target/[flags]
-
其中 pattern 支持正则匹配
-
在 target 使用
&
表示 pattern -
可以对 pattern 进行分组,在 target 中依次使用
\1,\2
表示组位置 -
flags 有四个可选项
-
数字,表明每一行将替换第几处匹配成功的地方
-
g, 表明新文本将会替换所有匹配的文本
-
p,表明原先行的内容要打印出来
-
w file,将替换的结果写入一个文件中
例如:
echo "I have a cat" | sed 's/.at/<&>/'
输出为I have a <cat>
在 posix 规范的正则中,点号
.
表示任意字符,因此 pattern 部分可以匹配到 cat 字符。在 target 部分中,用 & 表示 pattern 即 cat,因为最终结果为用替换了 原文中的 cat
echo "I have a cat" | sed 's/c\(.*\)/h\1/'
输出为I have a hat
pattern:
c\(.*\)
target:
h\1
由于 sed 本身仅支持 BRE 规则,如果要使用分组功能,需要给小括号
()
加上反斜线来转义,括号内部匹配任意字符串,这里分组匹配到了 at。在 target 部分,使用\1
表示第一个分组内容,也就是 at,因此 pattern 部分组合起来就是 hat。
对文本 text1(内容见上文) 做