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

发布于:2024-05-04 ⋅ 阅读:(24) ⋅ 点赞:(0)
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》,大家有兴趣可以买一本,也可以关注我,我更新完它。

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

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


网站公告

今日签到

点亮在社区的每一天
去签到