linux匹配文本内容sed,Linux“文本三剑客”之sed

“文本三剑客”中,grep是文本过滤器,而sed是基于行的文本流编辑器。

sed是将文件中的文本逐行读取到内存中进行处理。

sed工作原理

sed命令

2.1 OPTION

2.2 SCRIPT

sed使用示例

1 sed工作原理

sed有两个工作空间,Pattern space(模式空间)和Hold space(保持空间)。

f555c4e6048e

image.png

Pattern space 模式空间

sed会把文件内容的每一行复制一份出来放到自己的Pattern space中,在其中处理以后,处理的结果送到stdout(标准输出):

默认情况sed会处理每一行,但我们可以让sed处理只被模式(如正则表达式)匹配到的文本。

Pattern space中被用户给出的模式匹配到的内容,则edit(编辑)后再送到stdout。

如果不能匹配,则不做任何编辑操作,直接输出到stdout。

Hold space 保持空间

Hold space用于在使用高级编辑功能时,实现与Pattern space空间中的内容进行追加、覆盖、互换等操作。后边高级编辑示例中会详细解释。

2 sed命令

sed - stream editor for filtering and transforming text

sed [OPTION]... 'SCRIPT' [input-file]...

sed命令需要将命令选项OPTION和处理脚本SCRIPT结合使用,来对文本进行特定的处理动作。

2.1 OPTION

-n:不输出模式空间的内容至屏幕stdout

[默认情况下,会将不被pattern匹配到的内容直接输出到stdout,-n则不输出这部分内容]

-e script,--expression=script:多点编辑;

默认只支持一个script(被pattern匹配到的内容将被执行的编辑命令),加-e可以指定多个script。

如:sed -e 's@^#[[:space:]]*@@' -e '/^UUID/d' /etc/fstab

-f /PATH/TO/SED_SCRIPT_FILE

SED_SCRIPT_FILE中,每行都有一个script,从文件中逐行读取script,省去-e的繁琐

-r,--regexp-extended:支持扩展正则表达式

-i[SUFFIX],--in-place[=SUFFIX]:直接编辑原文件(有风险,用之前先做备份)(sed默认不直接编辑原文件)。

2.2 SCRIPT

SCRIPT由"地址定界"和"编辑命令"两部分组成,和vi编辑器的末行模式命令相似。两部分中间无空格。

地址定界的语法格式

地址定界为空,表示全文;

单地址:

N:指定一个行号,表示第N行;

/PATTERN/:给出一个模式,表示被模式匹配到的每一行。

地址范围:

M,N:表示从第M行到第N行;

M,+N:表示从第M行开始,到往后N行之间的所有行(包含第M行);

M,/PATTERN/:表示从第M行到被PATTERN匹配到的第一行之间的所有行

/PATTERN1/,/PATTERN2/:表示从被PATTERN1匹配到的第一行,到被PATTERN2匹配到的第一行之间的所有行。

用“~”表示步进:

如:1~2表示所有奇数行,2~2表示所有偶数行。

编辑命令

d:delete pattern space,删除模式匹配到的内容(模式空间中的内容)

d是一个特殊的操作

p:print the current pattern space:打印模式匹配到的内容(模式空间中的内容)

p也是一个特殊的操作,会将pattern匹配到的内容显示两遍,如果不加选项,显示结果为,模式空间中的全部内容+被pattern匹配到的内容;

如果只想显示被pattern匹配的内容,配合使用-n选项,将不显示默认输出的模式空间全部内容。

a \text:append,在模式匹配到的行后面追加文本“text”,支持使用\n(换行符号)实现多行追加(注意文本前用\转义)

i:insert,在模式匹配到的行前面插入文本“text”,支持使用\n(换行符号)实现多行插入(注意文本前用\转义)

比如,在fstab文件中所有以UUID开头的行前面加入注释:

sed '/^UUID/i # Add device based on UUID.' fstab

c \text:把匹配到的行替换为"text"(注意是整行替换!!);

w /PATH/TO/SOMEFILE:保存模式匹配到的行至指定的文件中;

例如:将fstab中所有以非#开头的行保存到当前目录下的fstab.new文件中:

sed '/[#]/w fstab.new' fstab

r /PATH/FROM/SOMEFILE:读取指定文件的内容至当前文件被模式匹配到的行后面;

例如:将/etc/issue文件中的内容显示到fstab文件第3行的后面:

sed '3r /etc/issue' fstab

=:为模式匹配到的行打印行号(在行的前面另起一个新行来打印行号);

例如:将fstab中所有以UUID开头的行都打印行号:

sed '/^UUID/=' fstab

!:条件取反(!放在地址定界和编辑命令之间)

地址定界!编辑命令

例如:前边有个例子,“将fstab中所有以非#开头的行保存到当前目录下的fstab.new文件中”

我们使用 “sed '/[#]/w fstab.new' fstab”;

在这里可以这样“ sed '/^#/!w fstab.new' fstab”,它表示所有#号开头的行都不写入fstab.new文件,即非#开头的行就写入。

s///:查找替换,其分隔符可自行指定,常用的有s@@@,s###等;

替换标记:

g:全局替换

w /PATH/TO/SOMEFILE:将替换成功的结果保存至指定文件中;

p:显示替换成功的行;

高级编辑命令

高级编辑命令用于Pattern space和Hold space中内容的追加、覆盖和互换,有以下几个:

Pttern space --> Hold space

h:把模式空间中的内容覆盖至 > 保持空间(hold space)中;

H:把模式空间中的内容追加至 >> 保持空间(hold space)中;

Hold space --> Pattern space

g:把保持空间中的内容覆盖至 > 模式空间中;

G:把保持空间中的内容追加至 >> 模式空间中;

模式匹配的下一行 --> Pattern space

n:覆盖读取匹配到的行的下一行至 > 模式空间中

N:追加读取匹配到的行的下一行至 >> 模式空间中

Pattern space Hold space

x:把模式空间中的内容与保持空间中的内容互换;

删除Pattern sapce中的行

d:删除模式空间中的行

D:删除多行模式空间中的所有行(多行模式空间比如,N命令追加到模式空间中行)

3 sed使用示例

普通编辑命令示例

sed是否用得好,主要是看SCRIPT的编写能力。

删除/etc/grub2.cfg文件中所有以空白字符开头的行的行首的所有空白字符:

sed 's@^[[:space:]]\+@@' /etc/grub2.cfg

删除/etc/fstab文件中所有以#开头的行的行首的#号及#后边的所有空白字符:

sed 's@^#[[:space:]]*@@' /etc/fstab

输出一个绝对路径给sed命令,要求取出其目录名,类似dirname命令执行结果:

echo "/var/log/messages" | sed 's@[^/]\+/\?$@@'

或使用-r选项支持扩展正则表达式:

echo "/var/log/messages" | sed -r 's@[^/]+/?$@@'

高级编辑命令示例与命令解析

要使用sed的高级编辑命令,需要对sed的工作流程非常熟悉。

sed -n 'n;p' FILE

显示偶数行(;分号用来分隔多个命令)

命令解析:

因为是n;p,没有地址定界,表示逐行读取所有内容。

1、首先读取第1行到pattern space,遇到第一个命令是n,覆盖读取下一行(也就是第2行)到pattern space,所以现在pattern space中的内容变为第2行(第1行被覆盖掉);

2、然后是p命令,将pattern space中的第2行显示出来;

3、接着读取第3行到pattern space,同上,显示第4行;

4、以此类推,显示所有偶数行。

注意:如果没有-n选项,则将显示全部内容,并且偶数行显示两遍。

sed '1!G;h;$!d' FILE

逆序显示文件内容,相当于tac

命令解析:

1、读取第1行到pattern space,先碰到“1!G”命令,表示第1行不做G操作;

2、然后碰到下一个命令“h”,表示将pattern space中的内容覆盖至hold space,就是将第1行内容复制到了hold space中;

3、接下来碰到“$!d”命令,表示将pattern space中不是最后一行的内容全部删除,pattern space中当前还有第1行的内容,则将其删除。第1行的读取到此结束。

4、接着读取第2行,“1!G”命令将hold space中的内容(第1行的内容)覆盖至pattern space,所以目前pattern space中的内容变为“第2行+第1行”;

5、然后碰到“h”命令,将pattern space中的内容(第2行+第1行)复制到hold space中(hold space中原来的第1行内容被覆盖掉),所以现在hold space中的内容为“第2行+第1行”;

6、下一个命令“$!d”,同上,将pattern space中的“第2行+第1行”内容删除。

第2行的读取到此结束。

7、以此类推,知道读取第n-1行结束时,hold space的内容为“第n-1行+第n-2行....第2行+第1行”,pattern space为空;

8、最后读取第n行,“1!G”命令将hold space内容追加到pattern space,则pattern space内容变为“第n行...第1行”;

9、“h”命令将pattern space的内容覆盖复制到hold space,则现在hold space的内容为“第n行...第1行”;

10、最后碰到“$!d”命令,因为是最后一行,则不删除pattern space的内容,所以pattern space中的内容还是“第n行...第1行”。

11、读取完全部内容后,默认输出pattern space中的全部内容,即“第n行...第1行”,将原内容逆序显示!

sed '$!d' FILE

取出最后一行,相当于tail -1

命令解析:

1、读取第1行到pattern space,pattern中的命令为“$!d”(不是最后一行,则删除),所以把第1行从pattern space中删了

2、依次类推,一直删到倒数第2行;

3、到最后一行,不删了,保留在pattern space中,然后输出到stdout。

其他几个高级编辑命令示例

sed '$!N;$!D' FILE:显示最后两行,相当于tail -2

sed '/^$/d;G' FILE:删除原有所有空白行,再为所有非空白行后添加一个空白行

sed 'n;d' FILE:显示奇数行;

sed 'G' FILE:在原有的每行后方添加一个空白行;

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值