windows ubuntu sed,awk,grep篇,6.sed 保持空间和模式空间命令

目录

[41.用保持空间替换模式空间(命令 x)](#41.用保持空间替换模式空间(命令 x))

[42.把模式空间的内容复制到保持空间(命令 h)](#42.把模式空间的内容复制到保持空间(命令 h))

[43.把模式空间内容追加到保持空间(命令 H)](#43.把模式空间内容追加到保持空间(命令 H))

[44.把保持空间内容复制到模式空间(命令 g)](#44.把保持空间内容复制到模式空间(命令 g))

[45.把保持空间追加到模式空间(命令 G)](#45.把保持空间追加到模式空间(命令 G))


Sed 有两个内置的存储空间:
z 模式空间:如你所知,模式空间用于 sed 执行的正常流程中。该空间 sed 内置的一
个缓冲区,用来存放、修改从输入文件读取的内容。
z 保持空间:保持空间是另外一个缓冲区,用来存放临时数据。Sed 可以在保持空间
和模式空间交换数据,但是不能在保持空间上执行普通的 sed 命令。我们已经讨论
过,每次循环读取数据过程中,模式空间的内容都会被清空,然而保持空间的内容
则保持不变,不会在循环中被删除。
请先建立如下文件,以用于保持空间的示例:
$ vi empnametitle.txt
John
Doe
CEO
Jason Smith
IT Manager
Raj Reddy
Sysadmin
Anand Ram
Developer
Jane Miller
Sales Manager
可以看到,在这个文件中,每个雇员的名称和职位位于连续的两行内。

41.用保持空间替换模式空间(命令x)

命令 x(Exchange) 交换模式空间和保持空间的内容。该命令本身没有多大用处,但如果和其
他命令配合使用,则非常强大了。
假定目前模式空间内容为 "line 1" ,保持空间内容为 "line 2" 。那么执行命令 x 后,模式空间的
内容变为 "line 2", 保持空间的内容变为 "line 1" 。
下面的例子打印管理者的名称,它搜索关键字'Manager'并打印之前的那一行:
$ sed --n -e '{x;n}' --e '/Manager/{x;p}' empnametitle.txt
Jason Smith
Jane Miller
上面命令也可写成 : sed -n 'x;n;/Manager/{x;p}' empnametitle.txt
提示: 如果你的 empnametitle.txt 文件,雇员名称和职位不是连续的,那么得不到上面的结
果。
上面例子中 :
z {x;n} -- x 交换模式空间和保持空间的内容; n 读取下一行到模式空间。在示例文件
中,保持空间保存的是雇员名称,模式空间保存的是职位。
z /Manager/{x;} -- 如果当前模式空间的内容包含关键 'Manager' ,那么就交换保持空
间和模式空间的内容,然后打印模式空间的内容。这就意味着,如果雇员职位中包
含 Manager, 那么该雇员的名称将被打印出来。
你也可以把上述命令保存在 sed 脚本中,然后执行,如下所示:
$ vim x.sed
#!/bin/sed -nf
x;n
/Manager/{x;p}
$ chmod u+x x.sed
$ ./x.sed empnametitle.txt
Jason Smith
Jane Miller

42.把模式空间的内容复制到保持空间(命令h)

命令 h(hold) 把模式空间的内容复制到保持空间,和命令 x 不同,命令 h 不会修改当前模式
空间的内容。执行命令 h 时,当前保持空间的内容会被模式空间的内容覆盖。
假定目前模式空间内容为 "line 1" ,保持空间内容为 "line 2" 。那么执行命令 h 后,模式空间
的内容仍然为 "line 1", 保持空间的内容则变为 "line 1" 。
打印管理者的名称:
$ sed -n -e '/Manager/!h' -e '/Manager/{x;p}' empnametitle.txt
Jason Smith
Jane Miller
上面例子中:
z /Manager/!h -- 如果模式空间内容不包含关键字 'Manager'( 模式后面的 ! 表示不匹配
该模式 ) ,那么复制模式空间内容到保持空间。 ( 这样一来,保持空间的内容可能会
是雇员名称或职位,而不是 'Manager'.) 注意,和前面的例子不同,这个例子中没有
使用命令 n 来获取下一行,而是通过正常的流程来读取后续内容。
z /Manager/{x;p} -- 如果模式空间内容包含关键字 'Manager' ,那么交换保持空间和模
式空间的内容,并打印模式空间的内容。这和我们在命令 x 的示例中的用法是相同
的。
你也可以把上面命令保存到 sed 脚本中执行:
$ vi h.sed
#!/bin/sed -nf
/Manager/!h
/Manager/{x;p}
$ chmod u+x h.sed
$ ./h.sed empnametitle.txtJason Smith
Jane Miller

43.把模式空间内容追加到保持空间(命令H)

大写 H 命令表示把模式空间的内容追加到保持空间,追加之前保持空间的内容不会被覆盖;
相反,它在当前保持空间内容后面加上换行符 \n ,然后把模式空间内容追加进来。
假定目前模式空间内容为 "line 1" ,保持空间内容为 "line 2" 。那么执行命令 H 后,模式空间
的内容没有改变,仍然为 "line 1", 保持空间的内容则变为 "line2\nline 1" 。
打印管理者的名称和职位(在不同的行上):
$ sed -n -e '/Manager/!h' -e '/Manager/{H;x;p}' empnametitle.txt
Jason Smith
IT Manager
Jane Miller
Sales Manager
上面例子中 :
z /Manager/!h -- 如果模式空间内容不包含关键字 'Manager'( 模式后面的 ! 表示不匹配
该模式 ) ,那么复制模式空间内容到保持空间。 ( 这样一来,保持空间的内容可能会
是雇员名称或职位,而不是 'Manager'.) 。这和之前使用命令 h 的方法是一样的。
z /Manager/{H;x;p} -- 如果模式空间内容包含关键字 'Manager' ,那么命令 H 把模式空
间的内容 ( 也就是管理者的职位 ) 作为新行追加到保持空间,所以保持空间内容会变
为 " 雇员名称 \n 职位 "( 职位包含关键字 Manager) 。然后命令 x 交换模式空间和保持
空间的内容,随后命令 p 打印模式空间的内容。
你也可以把上面命令保存到 sed 脚本中执行:
$ vi H-upper.sed
#!/bin/sed -nf
/Manager/!h
/Manager/{H;x;p}
$ chmod u+x H-upper.sed
$ ./H-upper.sed empnametitle.txt
Jason Smith
IT Manager
Jane Miller
Sales Manager如果想把雇员名称和职位显示在同一行,以分号分开,那么只需稍微修改一下即可,如下:
$ sed -n -e '/Manager/!h' -e '/Manager/{H;x;;s/\n/:/p}' empnametitle.txt
Jason Smith:IT Manager
Jane Miller:Sales Manager
这个例子除了在第二个 -e 后面的命令中加入了替换命令之外,和前面的例子一样。 H 、 x 和
p 都完成和之前相同的操作;在交换模式空间和保持空间之后,命令 s 把换行符 \n 替换为分
号,然后打印出来。
你也可以把上面命令保存到 sed 脚本中执行:
$ vi H1-upper.sed
#!/bin/sed -nf
/Manager/!h
/Manager/{H;x;s/\n/:/;p}
$ chmod u+x H1-upper.sed
$ ./H1-upper.sed empnametitle.txt
Jason Smith:IT Manager
Jane Miller:Sales Manager

44.把保持空间内容复制到模式空间(命令g)

命令 g(get) 把保持空间的内容复制到模式空间。
这样理解:命令 h 保持 (hold) 住保持空间 (hold space) ,命令 g 从保持空间获取 (get) 内容。
假定当前模式空间内容为 "line 1", 保持空间内容为 "line 2"; 执行命令 g 之后,模式空间内容变
为 "line 2" ,保持空间内容仍然为 "line 2" 。
打印管理者的名称:
$ sed -n -e '/Manager/!h' -e '/Manager/{g;p}' empnametitle.txt
Jason Smith
Jane Miller
上面例子中 :
z /Manager/!h -- 最近几个例子都在用它。如果模式空间内容不包含关键字 'Manager',
那么就把他复制到保持空间。
z /Manager/{g;p} -- 把保持空间的内容丢到模式空间中,然后打印出来
你也可以把上面命令保存到 sed 脚本中执行:
$ vi g.sed#!/bin/sed -nf
/Manager/!h
/Manager/{g;p}
$ chmod u+x g.sed
$ ./g.sed empnametitle.txt
Jason Smith
Jane Miller

45.把保持空间追加到模式空间(命令G)

大写 G 命令把当前保持空间的内容作为新行追加到模式空间中。模式空间的内容不会被覆
盖,该命令在模式空间后面加上换行符 \n ,然后把保持空间内容追加进去。
G 和 g 的用法类似于 H 和 h ;小写命令替换原来的内容,大写命令追加原来的内容。
假定当前模式空间内容为 "line 1" ,保持空间内容为 "line 2"; 命令 G 执行后,模式空间内容变
为 "line 1\nline 2", 同时保持空间内容不变,仍然为 "line 2" 。
以分号分隔,打印管理者的名称和职位:
$ sed -n -e '/Manager/!h' -e '/Manager/{x;G;s/\n/:/;p}' empnametitle.txt
Jason Smith:IT Manager
Jane Miller:Sales Manager
上面例子中:
z /Manager/!h -- 和前面的例子一样,如果模式空间内容不包含关键字 'Manager', 那么
就把他复制到保持空间。
z /Manager/{x;G;s/\n/:/;p} -- 如果模式空间包含 'Manager', 那么 :
x -- 交换模式空间和保持空间的内容。
G -- 把保持空间的内容追加到模式空间。
s/\n/:/ -- 在模式空间中,把换行符替换为分号 : 。
p 打印模式空间内容
注意:如果舍去命令 x ,即使用 /Manager/{G;s/\n/:/;p}, 那么结果会由
" 雇员职位 : 雇员名称 " 变成 " 雇员名称 : 雇员职位 "
也可把上述命令写到 sed 脚本中然后执行:
$ vi G-upper.sed
#!/bin/sed -nf
/Manager/!h
/Manager/{x;G;s/\n/:/;p}
$ chmod u+x G-upper.sed$ ./G-upper.sed empnametitle.txt
Jason Smith:IT Manager
Jane Miller:Sales Manager
资料来源于《SedandAwk101Hacks》,大家有兴趣可以买一本,也可以关注我,我更新完它。

曾经,我花费大半月将它们跑完,现在啥都忘了,还是要常用。

只为学习交流,不为获利,侵权联系立删。

相关推荐
码农小白9 分钟前
linux驱动:(22)中断节点和中断函数
linux·运维·服务器
4647的码农历程10 分钟前
Linux网络编程 -- 网络基础
linux·运维·网络
醉颜凉35 分钟前
银河麒麟桌面操作系统V10 SP1:取消安装应用的安全授权认证
运维·安全·操作系统·国产化·麒麟·kylin os·安全授权认证
C++忠实粉丝1 小时前
Linux环境基础开发工具使用(2)
linux·运维·服务器
康熙38bdc2 小时前
Linux 环境变量
linux·运维·服务器
存储服务专家StorageExpert2 小时前
DELL SC compellent存储的四种访问方式
运维·服务器·存储维护·emc存储
hakesashou3 小时前
python如何比较字符串
linux·开发语言·python
Ljubim.te3 小时前
Linux基于CentOS学习【进程状态】【进程优先级】【调度与切换】【进程挂起】【进程饥饿】
linux·学习·centos
cooldream20093 小时前
Linux性能调优技巧
linux
大G哥3 小时前
记一次K8S 环境应用nginx stable-alpine 解析内部域名失败排查思路
运维·nginx·云原生·容器·kubernetes