(共556篇)
全部分类

Sed教程
[ 未分类 ] 

关于 Sed, 看了很多文档,大部分中文文档都是用某种工具"直译"过来的,让我走了大量的弯路,这里对"sed"整理了一些用法和说明

学习之前需要明白的东西

sed 命令的工作流程:

  1. 逐行读取文件
  2. 把读取内容放进缓冲区
  3. 在缓冲区中对内容做一些增删改查的操作
  4. 把增删改查后的内容打印出来,或者保存到指定位置

注意默认情况下,sed 只修改缓冲区的内容,不会影响原文件!!!

命令

sed [options] [commands] files;

行模式查找

默认情况下,sed 命令会把缓冲区(修改后)的内容全部输出, 如果只想输出我们筛选出来的的行,可以使用-n参数, 和p命令配合, -n表示禁止输出缓冲区的内容, p命令表示输出符合我们条件或者是被我们修改后的内容

假设我有一个文件index.md, 内容是(为了表名输出的内容是第几行,我在每一行前面加了行数):

1
2
3
4
5
6
#1 Welcome China
#2 Hello world
#3 Hello India
#4 Hello English
#5 Hello world
#6 Welcome USA

sed -n '3 p' index.md

这里的3, 既是开始位置,又是结束位置,所以会获取第三行的内容

1
Hello India

sed -n '1,4 p' index.md

1是开始行数,4是结束行数, 开始和结束位置以逗号分隔:

1
2
3
4
Welcome China
Hello world
Hello India
Hello English

sed -n '2,+2 p' index.md

m行开始, 获取m行和m行之后的n行:

1
2
3
Hello world
Hello India
Hello English

sed -n '1~2 p' index.md

表示从第 1 行开始获取,每隔 1 行获取 1 行内容,(注意 MacOS 中不支持此语法, 会抛出错误)

1
2
3
Welcome China
Hello India
Hello world

sed -n '1~3 p' index.md

表示从第 1 行开始,每隔 3 行获取 1 行内容:

1
2
Welcome China
Hello English

sed -n '4,$ p ' index.md,

表示 从第 4 行输出到最后一行,这里的$表示最后一行

1
2
3
Hello English
Hello world
Welcome USA

字符串模式查找

还是以index.md为例:

sed -n '/world/ p' index.md

这里/world/既是开始位置,也是结束位置,表示查找所有包含了world的行:

1
2
Hello world
Hello world

sed -n '/India/, /Japan/ p' index.md

输出从包含了India的行,到包含Japan的行,由于包含India之后的行中没有找到包含Japan的行,所以会直接输出到文件结束

1
2
3
4
Hello India
Hello English
Hello world
Welcome USA

sed -n '/India/, /English/ p' index.md:

先找到包含India的行,再往后找到包含English的行,将这个范围内的行内容全部输出.

1
2
Hello India
Hello English

sed -n '/world/, /India/ p' index.md,

1
2
3
4
Hello world
Hello India
Hello world
Welcome USA

为什么这里的输出有 4 行, 因为文件中包含world的有两行,sed对于起始位置会全局查找,找到所有包含了world的行分别作为起始位置, 再从包含world的行之后查找包含India的行内容, 第一次包含world的行之后, 顺利找到了包含India的行,所以会输出 2 行内容, 第二次包含world的行之后,没有找到包含India的行,所以会直接输出到文件末尾

现在可以总结一下:

  1. 对于起始位置, sed命令都会在整个文件中查找所有包含起始位置字符串的行(下面叫起始行), 再从该行之后查找包含结束字符串的行(下面叫结束行)
  2. 如果找到了结束行,则输出起始行到结束行中间的所有行(包含起始行和结束行),
  3. 如果没有找到结束行,则输出起始行到文件结尾的所有行(包含起始行)
  4. sed -n '/world/ p' index.md模式,可以当做是同时指定了起始字符串和结束字符串,只会输出包含字符串的行

混合模式

sed -n '1 ,/world/ p' index.md

这里1是起始行位置, /world/表示从第 1 行的下一行开始查找包含world的行,是结束行位置,所以输出结果是:

1
2
Welcome China
Hello world

sed -n '2, /world/ p' index.md

第 2 行是起始行,之后第一次包含了world的行是结束行:

1
2
3
4
Hello world
Hello India
Hello English
Hello world

再来看一个反过来的例子sed -n '/world/, 4 p' index.md:

1
2
3
4
Hello world
Hello India
Hello English
Hello world

回忆一下字符串模式的总结, 起始位置是字符串模式,所以先找到所有包含world的行,分别作为起始行, 第一个world的起始行行数是 2,小于 4,所以输出了 2~4 行, 第二个world的起始行行数是 5,大于 4,所以只输出地 5 行.

删除 d 命令

sed '2d' index.md:删除第 2 行内容

1
2
3
4
5
Welcome China
Hello India
Hello English
Hello world
Welcome USA