结合自己使用需要,主要根据三十分钟学会SED简化整理所得。
用途
sed是一个文本解析转换工具,主要用于以下用途:
- 文本替换
- 选择性的输出文本文件
- 从文本文件的某处开始编辑
- 无交互式的对文本文件进行编辑等
工作流
SED遵循简单的工作流:读取,执行和显示。
读取: SED从输入流(文件,管道或者标准输入)中读取一行并且存储到它叫做 模式空间(pattern buffer)的内部缓冲区
执行: 默认情况下,所有的SED命令都在模式空间中顺序的执行,除非指定了行的地址,否则SED命令将会在所有的行上依次执行
显示: 发送修改后的内容到输出流。在发送数据之后,模式空间将会被清空。
在文件所有的内容都被处理完成之前,上述过程将会重复执行
注意事项
- 模式空间 (pattern buffer) 是一块活跃的缓冲区,在sed编辑器执行命令时它会保存待检查的文本
- 默认情况下,所有的SED命令都是在模式空间中执行,因此输入文件并不会发生改变
- 还有另外一个缓冲区叫做** 保持空间** (hold buffer),在处理模式空间中的某些行时,可以用保持空间来临时保存一些行。在每一个循环结束的时候,SED将会移除模式空间中的内容,但是该缓冲区中的内容在所有的循环过程中是持久存储的。SED命令无法直接在该缓冲区中执行,因此SED允许数据在 **保持空间 **和 模式空间之间切换
- 初始情况下,保持空间 和** 模式空间** 这两个缓冲区都是空的
- 如果没有提供输入文件的话,SED将会从标准输入接收请求
- 如果没有提供地址范围的话,默认情况下SED将会对所有的行进行操作
基础语法
sed [-n] [-e] 'command(s)' files
sed [-n] -f scriptfile files
第一种方式在命令行中使用单引号指定要执行的命令,第二种方式则指定了包含SED命令的脚本文件。
标准选项
- -n:默认情况下,模式空间中的内容在处理完成后将会打印到标准输出,该选项用于阻止该行为
$ sed '' hello.txt #创建个hello的txt,''表示没输入任何命令
hello
$ sed -n '' hello.txt
- -e:指定要执行的命令,使用该参数,我们可以指定多个命令,让我们打印每一行两次:
$ sed -e '' -e 'p' hello.txt
hello
hello
- -f: 指定包含要执行的命令的脚本文件
$ echo "p" > commands
$
$ sed -n -f commands hello.txt
hello
行寻址
默认情况下,在SED中使用的命令会作用于文本数据的所有行。如果只想将命令作用于特定的行或者某些行,则需要使用 行寻址 功能。
[address]command #基本语法
先创建一个文本用于演示.
$ cat demo.txt
1 one
2 two
3 three
4 four
5 five
6 six
1.以数字形式表示的行区间
指定行。
$ sed -n '3p' demo.txt #p命令是打印出模式空间中的内容
3 three
用逗号确定范围
$ sed -n '2,4p' demo.txt
2 two
3 three
4 four
$符号表示最后一行
$ sed -n '4,$ p' demo.txt
4 four
5 five
6 six
SED还提供了另外两种操作符用于指定地址范围,第一个是加号(+)操作符,它可以与逗号(,)操作符一起使用,例如 M, +n 将会打印出从第M行开始的下n行
$ sed -n '2,+2p' demo.txt
2 two
3 three
4 four
我们还可以使用波浪线操作符()指定地址范围,它使用MN的形式,它告诉SED应该处理M行开始的每N行。例如,50~5匹配行号50,55,60,65等,让我们只输出文件中的奇数行
$ sed -n '1~2p' demo.txt
1 one
3 three
5 five
注意,如果使用的是Mac系统自带的sed命令,可能不支持~和+操作符。可以使用brew install gnu-sed --with-default-names重新安装GNU-SED。
2.使用文本过滤器
/pattern/command #一般格式
$ sed -n '/three/ p' demo.txt
3 three
规则与数字表示一样,也可以与数字表示配合使用.
$ sed -n '/one/,/three/ p' demo.txt
1 one
2 two
3 three
$ sed -n '/3/ p' demo.txt
3 three
基本命令
- 删除命令 d
[address1[,address2]]d
address1和address2是开始和截止地址,它们可以是行号或者字符串匹配模式,这两种地址都是可选的。
注意的是,该命令只会移除模式空间中的行,但原始内容不会改变。
$ sed '3,5 d' demo.txt
1 one
2 two
6 six
- 文件写入命令 w
SED提供了 write 命令用于将模式空间中的内容写入到文件
$ sed -n '2,3 w junk.txt' demo.txt
$ cat junk.txt
2 two
3 three
- 追加命令 a
[address]a Append text
$ sed '2 a 9 nine' demo.txt
1 one
2 two
9 nine
3 three
4 four
5 five
6 six
-
插入命令 i
与a相同,不过是在匹配的位置前增加一行。 - 行替换命令 c
SED通过 c 提供了 change 和 replace 命令,该命令帮助我们使用新文本替换已经存在的行,当提供行的地址范围时,所有的行都被作为一组被替换为单行文本
$ sed '3,5 c 9 nine' demo.txt
1 one
2 two
9 nine
6 six
- 替换命令 s
[address1[,address2]]s/pattern/replacement/[flags]
$ sed 's/one/first/' demo.txt
1 first
2 two
3 three
4 four
5 five
6 six
在SED中,使用替换命令的时候默认只会对第一个匹配的位置进行替换.
以下有一些参数可供使用。
g对所有匹配的内容进行替换。
数字n: 只替换第n次匹配。
p:只输出改变的行。
w:存储改变的行到文件。比如
sed 's/one/first/w demoCopy.txt' demo.txt
i:匹配时忽略大小写。
排除命令 !
$ sed -n '/two/ !p' demo.txt
1 one
3 three
4 four
5 five
6 six
保持空间
在处理模式空间中的某些行时,可以用保持空间来临时保存一些行。有5条命令可用来操作保持空间
命令 | 作用 |
---|---|
h | 将模式空间复制到保持空间 |
H | 将模式空间附加到保持空间 |
g | 将保持空间复制到模式空间 |
G | 将保持空间附加到模式空间 |
x | 交换模式空间和保持空间的内容 |
$ sed -n '1!G;h;$p' demo.txt
6 six
5 five
4 four
3 three
2 two
1 one
- 1!G 这句的意思是出了第一行之外,处理每一行的时候都将保持空间中的内容追加到模式空间(正序->倒序)
- h 将模式空间中的内容复制到保持空间以备下一行匹配的时候追加到下一行的后面
- $p 如果匹配到最后一行的话则输出模式空间中的内容
- 上述步骤不断重复直到文本结束刚好将文件内容翻转了一次