sed 保持空间命令之 g、G 的执行逻辑

目录

1. 将保持空间的内容复制到模式空间

2. 在每行后面加一空行

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

4. 用 sed 加行号并模拟 tac


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

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

        命令 g(get)把保持空间的内容复制到模式空间。假定当前模式空间内容为“line 1”,保持空间内容为“line 2”,执行命令 g 之后,模式空间内容变为“line 2”,保持空间内容仍然为“line 2”。

1. 将保持空间的内容复制到模式空间

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

John Doe
CEO
Jason Smith
IT Manager
Raj Reddy
Sysadmin
Anand Ram
Developer
Jane Miller
Sales Manager

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

#sed -n -e '/Manager/!h' -e '/Manager/{g;p}' empnametitle.txt
Jason Smith
Jane Miller
#

        本例中:

  • /Manager/!h 的作用是如果模式空间内容不包含关键字 Manager,那么就把它复制到保持空间。
  • /Manager/{g;p} 的作用是如果模式空间内容包含关键字 Manager,则把保持空间的内容复制到模式空间中,然后打印出来。

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

循环次数

模式空间

保持空间

操作

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 脚本中执行:

  1. 创建内容如下的脚本文件 g.sed
    #!/bin/sed -nf
    /Manager/!h
    /Manager/{g;p}

  2. 修改脚本文件的模式为可执行
    chmod u+x g.sed

  3.  执行脚本
    #./g.sed empnametitle.txt
    Jason Smith
    Jane Miller
    #

        大写 G 命令把当前保持空间的内容作为新行追加到模式空间中。模式空间的内容不会被覆盖,该命令在模式空间后面加上换行符 \n,然后把保持空间内容追加进去。G 和 g 的用法类似于 H 和 h,小写命令替换原来的内容,大写命令追加原来的内容。

        假定当前模式空间内容为“line 1”,保持空间内容为“line 2”,命令 G 执行后,模式空间内容变为“line 1\nline 2”,同时保持空间内容不变,仍然为“line 2”。

2. 在每行后面加一空行

#echo -e "line1\nline2\nline3" | sed 'G'
line1

line2

line3

#

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

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

John Doe
CEO
Jason Smith
IT Manager
Raj Reddy
Sysadmin
Anand Ram
Developer
Jane Miller
Sales Manager

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

#sed -n -e '/Manager/!h' -e '/Manager/{x;G;s/\n/:/;p}' empnametitle.txt
Jason Smith:IT Manager
Jane Miller:Sales Manager
#

        本例中:

  • /Manager/!h 的作用是如果模式空间内容不包含关键字 Manager,那么就把它复制到保持空间。
  • /Manager/{x;G;s/\n/:/;p} 的作用是如果模式空间包含 Manager,那么:
    • x 交换模式空间和保持空间的内容。
    • G 把保持空间的内容追加到模式空间。
    • s/\n/:/ 在模式空间中,把换行符替换为冒号。
    • 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

Jason Smith

Jason Smith\nIT Manager

Jason Smith:IT Manager

Jason Smith

IT Manager

IT Manager

IT Manager

IT Manager

x =>

G =>

s/\n/:/ =>

p Jason Smith:IT 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

Jane Miller

Jane Miller\nSales Manager

Jane Miller:Sales Manager

Jane Miller

Sales Manager

Sales Manager

Sales Manager

x =>

G =>

s/\n/:/ =>

p Jane Miller:Sales Manager

        注意:如果舍去命令 x,即使用 /Manager/{G;s/\n/:/;p},那么结果会由“雇员职位: 雇员名称”变成”雇员名称: 雇员职位”。

        也可把上述命令写到 sed 脚本中然后执行:

  1. 创建内容如下的脚本文件 G-upper.sed
    #!/bin/sed -nf
    /Manager/!h
    /Manager/{x;G;s/\n/:/;p}

  2. 修改脚本文件的模式为可执行
    chmod u+x G-upper.sed

  3. 执行脚本
    #./G-upper.sed empnametitle.txt
    Jason Smith:IT Manager
    Jane Miller:Sales Manager
    #

4. 用 sed 加行号并模拟 tac

        cat -n 可以加行号,tac 可以按行反转输出,例如:

#echo -e "line1\nline2\nline3\nline4\nline5" | cat -n | tac
     5	line5
     4	line4
     3	line3
     2	line2
     1	line1
#

        用 sed 也可以达到相同的效果:

#echo -e "line1\nline2\nline3\nline4\nline5" | sed '=' | sed 'N;s/\n/  /g;s/^/     /g;' | sed -n '1!G;h;$p'
     5  line5
     4  line4
     3  line3
     2  line2
     1  line1
#

        第一个 sed 命令用于在每行前面加行号:

#echo -e "line1\nline2\nline3\nline4\nline5" | sed '='
1
line1
2
line2
3
line3
4
line4
5
line5
#

        第二个 sed 命令将行号与正文拼成一行,并对标 cat -n 的输出添加相应的空格:

#echo -e "line1\nline2\nline3\nline4\nline5" | sed '=' | sed 'N;s/\n/  /g;s/^/     /g;'
     1  line1
     2  line2
     3  line3
     4  line4
     5  line5
#

        N 命令将下一行添加到模式空间中,结果是当前读入行和用 N 命令添加的下一行拼成“一行”:

1\nline1
2\nline2
3\nline3
4\nline4
5\nline5

        s/\n/  /g;s/^/     /g; 命令将 \n 替换成两个空格,并在行头添加四个空格,为的是让输出和 cat -n 完全一样。

        最后的 sed -n '1!G;h;$p' 命令模拟 tac 反转输出行,这个命令的工作原理是:

  1. 1!G:对于不是第一行的每一行,将保持空间的内容追加到模式空间。由于在第一行之前没有内容在保持空间中,所以这一行对第一行没有影响。
  2. h:将模式空间的内容复制到保持空间中。
  3. $p:在文件的最后一行,打印模式空间的内容。
     

        完整的执行流程如下表所示(为简化演示,没显示行头的空格)。

循环次数

模式空间

保持空间

操作

1

1  line1

1  line1

\n

1  line1

1  line1

h =>

2

2  line2

2  line2\n1  line1

2  line2\n1  line1

1  line1

1  line1

2  line2\n1  line1

2  line2\n1  line1

G =>

h =>

3

3  line3

3  line3\n2  line2\n1  line1

3  line3\n2  line2\n1  line1

2  line2\n1  line1

2  line2\n1  line1

3  line3\n2  line2\n1  line1

3  line3\n2  line2\n1  line1

G =>

h =>

4

4  line4

4  line4\n3  line3\n2  line2\n1  line1

4  line4\n3  line3\n2  line2\n1  line1

3  line3\n2  line2\n1  line1

3  line3\n2  line2\n1  line1

4  line4\n3  line3\n2  line2\n1  line1

4  line4\n3  line3\n2  line2\n1  line1

G =>

h =>

5

5  line5

5  line5\n4  line4\n3  line3\n2  line2\n1  line1

5  line5\n4  line4\n3  line3\n2  line2\n1  line1

4  line4\n3  line3\n2  line2\n1  line1

4  line4\n3  line3\n2  line2\n1  line1

5  line5\n4  line4\n3  line3\n2  line2\n1  line1

G =>

h =>

p 5  line5\n4  line4\n3  line3\n2  line2\n1  line1

        但是需要注意,这种方法实际上是在文件处理完成后才输出反转的内容,而不是在读取文件时逐行反转。对于真正的逐行反向输出,应该考虑使用 tac 或者编写一个小的脚本(如使用 awk、perl 或 bash)来实现。例如,使用 awk 实现逐行反向输出的脚本可能如下所示:

awk '{lines[NR] = $0} END {for (i=NR; i>0; i--) print lines[i]}' filename

        这个 awk 脚本将文件的每一行存储在数组 lines 中,然后在文件处理完成后,从数组的末尾开始向前遍历并打印每一行,从而实现反向输出的效果。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mfbz.cn/a/773099.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

抗震支吊架安装

抗震支吊架系统安装指导 设计要求: 本工程采用抗震支吊架系统,请根据深化设计提供的图纸及安装材料表等进行安装。 材料要求: 符合 CJ/T476-2015《建筑机电设备抗震支吊架通用技术条件》及 CECS 420:2015《抗震支吊架安装及验收规程》 槽…

Go语言--延迟调用defer、获取命令行参数、局部变量以及全局变量

延迟调用defer 关键字 defer 用于延迟一个函数或者方法(或者当前所创建的匿名函数)的执行。注意,defer语句只能出现在函数或方法的内部。 defer 语句经常被用于处理成对的操作,如打开、关闭、连接、断开连接、加锁、释放锁。通过defer 机制&#xff0…

生态共建 | 华宇TAS应用中间件与新华三服务器完成兼容互认证

近日,华宇TAS应用中间件完成与新华三技术有限公司的R4930系列和R4970 G7服务器的兼容适配,认证测试报告显示,双方产品兼容性良好,运行稳定、安全,可以满足用户对双方功能的要求。 新华三技术有限公司 新华三技术有限公…

Pandas数据清洗实战:精准捕捉并优雅过滤异常值,让数据分析更可靠!

1.describe():查看每一列的描述性统计量 # 导包 import numpy as np import pandas as pddf pd.DataFrame(datanp.random.randint(0,10,size(5,3)),indexlist("ABCDE"),columns["Python","NumPy","Pandas"]) dfdf.descri…

SQL MINUS 运算符:查找数据集之间的差异

在 SQL 中,MINUS 运算符在查询中起着至关重要的作用,它允许开发人员识别和检索存在于一个数据集中但不存在于另一个数据集中的记录。本文探讨了 SQL 中 MINUS 运算符的功能、用法和实际应用,强调了它在数据分析和操作任务中的重要性。 理解 …

adobe pdf设置默认打开是滚动而不是单页视图

上班公司用adobe pdf,自己还不能安装其它软件。 每次打开pdf,总是默认单页视图,修改滚动后,下次打开又 一样,有时候比较烦。 后面打开编辑->首选项, 如下修改,下次打开就是默认滚动了

开源六轴协作机械臂myCobot280实现交互式乘法!让学习充满乐趣

本文经作者Fumitaka Kimizuka 授权我们翻译和转载。 原文链接:myCobotに「頷き」「首振り」「首傾げ」をしてもらう 🤖 - みかづきブログ・カスタム 引言 Fumitaka Kimizuka 创造了一个乘法表系统,帮助他的女儿享受学习乘法表的乐趣。她可以…

FPGA问题

fpga 问题 ep2c5t144 开发板 第一道坎,安装软件;没有注册,无法产生sop文件,无法下载 没有相应的库的quartus ii版本,需要另下载 第二道坎,模拟器的下载,安装; 第三道,v…

Camera Raw:红眼

Camera Raw 的红眼 Red Eye面板可高效地修正照片中的红眼现象。 红眼现象通常是由于闪光灯直接照射到眼睛内的视网膜所引起的,在摄影中常见于低光环境下的拍摄,尤其是在人物和宠物照片中。 在一些老照片中可能存在红眼现象,现代摄影技术基本上…

图像的反转

图像颜色的反转一般分为两种:一种是灰度图片的颜色反转,另一种是彩色图像的颜色反转。 本节使用的原图如下: 1.1 灰度图像颜色反转 灰度图像每个像素点只有一个像素值来表示,色彩范围在0-255之间,反转方法255-当前像…

Anaconda+Pycharm两个软件从头到尾下载流程

前言: 1、使用教程前,请将电脑上的所有的Python卸载掉。再下载Anaconda,Anaconda这个软件里面就含有python。 彻底删除python方法: 1、计算机——属性——高级系统设置——环境变量 2、查看电脑用户自己设计的环境变量&#x…

探索如何赋予对象迭代魔法,轻松实现非传统解构赋值的艺术

前言 今天下午在网上冲浪过程中看到这样一个问题 面试题:如何让 var [a, b] {a: 1, b: 2} 解构赋值成功? 据说是某大厂面试题,于是我学习了一下这个问题,写下这篇文章记录一下。 学习过程 要想解决这个问题首先要知道什么是解…

运维锅总详解计算机缓存

本文从OSI模型中的每一层缓存介绍、常见开源中间件缓存举例、TCP/IP协议栈中的缓存机制、操作系统中的缓存、访问缓存数据的时间范围统计等方面对计算机中的缓存进行详细介绍。希望对您有所帮助! 一、OSI模型中的每一层缓存 1. 物理层(Physical Layer&…

人工智能系列-numpy(一)

🌈个人主页:羽晨同学 💫个人格言:“成为自己未来的主人~” Numpy是python语言的一个拓展程序库,支持大量的维度数组与矩阵计算,此外也针对数组运算提供大量的数学函数库 NumPy支持的数据类型比Python内置的类型要…

SwiftUI中List的liststyle样式及使用详解添加、移动、删除、自定义滑动

SwiftUI中的List可是个好东西,它用于显示可滚动列表的视图容器,类似于UITableView。在List中可以显示静态或动态的数据,并支持垂直滚动。List是一个数据驱动的视图,当数据发生变化时,列表会自动更新。针对List&#xf…

PyMuPDF 操作手册 - 09 API - Page属性方法和简短说明

文章目录 一、Page属性方法和简短说明一、Page属性方法和简短说明 https://pymupdf.readthedocs.io/en/latest/page.html Method/Attribute属性方法Short Description简短说明Page.add_caret_annot()仅限 PDF:添加插入符号注释Page.add_circle_annot()仅限 PDF:添加圆圈…

前端面试题7(单点登录)

如何实现单点登录 单点登录(Single Sign-On,简称SSO)是一种允许用户在多个应用系统中只需登录一次,就可以访问所有相互信任的应用系统的认证技术。实现前端单点登录主要依赖于后端的支持和一些特定的协议,如OAuth、Ope…

Postman使用教程

传统接口风格 RESTful风格 使用Postman完成测试用例目标: Postman教程 (1)准备工作,下载Postman新建 (2)登录接口调试-获取验证码 (3)登录接口调试-登录 (4)…

python库(2):Passlib库

1 Passlib简介 Passlib库就是一个强大的工具,专门用于密码的安全存储和验证。本文将介绍Passlib库的基本概念、功能和使用方法,帮助更好地理解和应用密码安全技术。 Passlib是一个用于密码加密、哈希和验证的Python库,它提供了多种密码哈希…

STM32 HAL库实现硬件IIC通信

文章目录 一. 前言二. 关于IIC通信三. IIC通信过程四. STM32实现硬件IIC通信五. 关于硬件IIC的Bug 一. 前言 最近正在DIY一款智能电池,需要使用STM32F030F4P6和TI的电池管理芯片BQ40Z50进行SMBUS通信。SMBUS本质上就是IIC通信,项目用到STM32CubeMXHAL库…