前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >sed 保持空间命令之 H 的执行逻辑

sed 保持空间命令之 H 的执行逻辑

作者头像
用户1148526
发布2024-07-08 10:43:32
610
发布2024-07-08 10:43:32
举报
文章被收录于专栏:Hadoop数据仓库

sed 有两个内置的存储空间:

  • 模式空间:该空间是 sed 内置的一个缓冲区,是 sed 执行的正常流程中,暂存当前处理行的空间。每处理完一行都会清空模式空间再读取下一行。模式空间初始为空。
  • 保持空间:保持空间是另外一个缓冲区,用来存放临时数据,以便在后续处理中使用。与模式空间不同,保持空间的内容不会在循环中被删除。不能在保持空间上执行普通的 sed 命令。保持空间初始为一个换行符。

大写 H 命令表示把模式空间的内容追加到保持空间,追加不会覆盖保持空间的内容。当向初始保持空间追加内容时,因为保持空间初始内容为一个换行符 \n,所以直接把模式空间内容追加进来。当保持空间已经有内容时,H 命令在当前保持空间内容后面加上换行符 \n,然后再把模式空间内容追加进来。

假定目前模式空间内容为“line 1”,保持空间内容为“line 2”。那么执行命令 H 后,模式空间的内容没有改变,仍然为“line 1”,保持空间的内容则变为“line2\nline 1”。

以下是一些使用 H 命令的例子。

1. 追加文本到保持空间

代码语言:javascript
复制
#echo "Hello World" | sed -n 'H; x; p;'

Hello World
#

这个 sed 脚本会将模式空间的内容追加到保持空间,然后交换模式空间和保持空间的内容,使得保持空间的内容被打印出来。从输出可以看到比原始文本多了第一行的空行(保持空间的初始换行符)。

2. 追加并分隔文本到保持空间

代码语言:javascript
复制
#echo -e "Hello\nWorld" | sed -n 'H; x; $!d; x; p'
World
#

这个 sed 脚本会在追加文本到保持空间的同时追加一个换行符。完整的执行流程如下表所示。

循环次数

模式空间

保持空间

操作

1

Hello Hello \nHello 空

\n \nHello Hello Hello

H => x => d =>

2

World World Hello\nWorld World

Hello Hello\nWorld World Hello\nWorld

H => x => x => p World

注意,第一行的 $!d 命令会清空模式空间,并启动下一个循环,这实际上会导致跳过其后的 x; p 命令,直到最后一行。

3. 模式空间到保持空间的逐行复制、隔行匹配、分行打印

示例文本 empnametitle.txt 的内容如下:

代码语言:javascript
复制
John Doe
CEO
Jason Smith
IT Manager
Raj Reddy
Sysadmin
Anand Ram
Developer
Jane Miller
Sales Manager

在这个文件中,每个员工的姓名和职位位于连续的两行内。下面的命令在不同行上分别打印管理者的名称和职位。

代码语言:javascript
复制
#sed -n -e '/Manager/!h' -e '/Manager/{H;x;p}' empnametitle.txt
Jason Smith
IT Manager
Jane Miller
Sales Manager
#

这个例子中:

  • /Manager/!h 是将模式空间中不包含关键字 Manager 的内容复制到保持空间。这样保持空间的内容可能会是雇员名称或职位,但不是 Manager。
  • /Manager/{H;x;p} 的作用是如果模式空间内容包含关键字 Manager,那么命令 H 把模式空间的内容(也就是管理者的职位)作为新行追加到保持空间,所以保持空间内容会变为“雇员名称\n职位”(职位包含关键字Manager)。然后命令 x 交换模式空间和保持空间的内容,随后命令 p 打印模式空间的内容。

完整的执行流程如下表所示。

循环次数

模式空间

保持空间

操作

1

John Doe John Doe 空

\n John Doe John Doe

h =>

2

CEO CEO 空

John Doe CEO CEO

h =>

3

Jason Smith Jason Smith 空

CEO Jason Smith Jason Smith

h =>

4

IT Manager IT Manager Jason Smith\nIT Manager 空

Jason Smith Jason Smith\nIT Manager IT Manager IT Manager

H => x => p Jason Smith\nIT Manager =>

5

Raj Reddy Raj Reddy 空

IT Manager Raj Reddy Raj Reddy

h =>

6

Sysadmin Sysadmin 空

Raj Reddy Sysadmin Sysadmin

h =>

7

Anand Ram Anand Ram 空

Sysadmin Anand Ram Anand Ram

h =>

8

Developer Developer 空

Anand Ram Developer Developer

h =>

9

Jane Miller Jane Miller 空

Developer Jane Miller Jane Miller

h =>

10

Sales Manager Sales Manager Jane Miller\n Sales Manager

Jane Miller Jane Miller \nSales Manager Sales Manager

H => x => p Jane Miller\n Sales Manager

也可以把命令保存到 sed 脚本中执行:

创建内容如下的脚本文件 H-upper.sed

代码语言:javascript
复制
#!/bin/sed -nf
/Manager/!h
/Manager/{H;x;p}

修改脚本文件的模式为可执行

代码语言:javascript
复制
chmod u+x H-upper.sed

执行脚本

代码语言:javascript
复制
#./H-upper.sed empnametitle.txt
Jason Smith
IT Manager
Jane Miller
Sales Manager
#

如果想把雇员名称和职位显示在同一行,并以冒号分开,那么只需稍微修改一下即可:

代码语言:javascript
复制
#sed -n -e '/Manager/!h' -e '/Manager/{H;x;s/\n/:/g;p}' empnametitle.txt
Jason Smith:IT Manager
Jane Miller:Sales Manager
#

这个例子除了在第二个 -e 后面的命令中加入了替换命令之外,和前面的例子一样。H、x 和 p 都完成和之前相同的操作。在交换模式空间和保持空间之后,命令 s 把换行符 \n 替换为分冒号,然后打印出来。

同样可以把上面命令保存到 sed 脚本中执行:

创建内容如下的脚本文件 H1-upper.sed

代码语言:javascript
复制
#!/bin/sed -nf
/Manager/!h
/Manager/{H;x;s/\n/:/g;p}

修改脚本文件的模式为可执行

代码语言:javascript
复制
chmod u+x H1-upper.sed

执行脚本

代码语言:javascript
复制
#./H1-upper.sed empnametitle.txt 
Jason Smith:IT Manager
Jane Miller:Sales Manager
#
本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2024-07-08,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 1. 追加文本到保持空间
  • 2. 追加并分隔文本到保持空间
  • 3. 模式空间到保持空间的逐行复制、隔行匹配、分行打印
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档