sed 中的“保留空间”和“模式空间”的概念

2024-11-06 08:35:00
admin
原创
37
摘要:问题描述:我对 sed 中的两个概念感到困惑:保留空间和模式空间。有人能帮忙解释一下吗?以下是该手册的片段:h H Copy/append pattern space to hold space. g G Copy/append hold space to pattern space. n N ...

问题描述:

我对 sed 中的两个概念感到困惑:保留空间和模式空间。有人能帮忙解释一下吗?

以下是该手册的片段:

h H    Copy/append pattern space to hold space.
g G    Copy/append hold space to pattern space.

n N    Read/append the next line of input into the pattern space.

这六个命令确实让我困惑。


解决方案 1:

当 sed 逐行读取文件时,当前已读取的行将插入到模式缓冲区(模式空间)中。模式缓冲区就像临时缓冲区,是存储当前信息的暂存器。当您告诉 sed 打印时,它会打印模式缓冲区。

保持缓冲区/保持空间就像一个长期存储,这样您就可以捕获某些内容,将其存储起来,并在 sed 处理另一行时重新使用它。您不能直接处理保持空间,而是需要将其复制或附加到模式空间,如果您想对其进行处理。例如,print 命令p仅打印模式空间。同样,s对模式空间进行操作。

以下是一个例子:

sed -n '1!G;h;$p'

(-n 选项禁止自动打印行)

这里有三个命令:1!Gh$p1!G有一个地址,1(第一行),但!意味着该命令将在第一行以外$p的所有地方执行。另一方面,只会在最后一行执行。所以发生的事情是这样的:

  1. 读取第一行并自动插入到模式空间中

  2. 在第一行,第一个命令不执行;h将第一行复制到保存空间。

  3. 现在第二行替换了模式空间中的所有内容

  4. 在第二行,我们首先执行G,将保留缓冲区的内容附加到模式缓冲区,并用换行符分隔。模式空间现在包含第二行、换行符和第一行。

  5. 然后,h命令将模式缓冲区的连接内容插入到保持空间中,该保持空间现在保存了两条和一条反转的线。

  6. 我们继续第三行——转到上面的点 (3)。

最后,在读取最后一行并将保留空间(包含所有先前的行,顺序相反)附加到模式空间后,模式空间将使用 打印p。正如您所猜测的,上面的操作与tac命令完全相同 - 反向打印文件。

解决方案 2:

@Ed Morton:我不同意你的观点。我发现,sed想出一种优雅的多行 grepping 方法非常有用且简单(一旦你理解了模式和保留缓冲区的概念)。

例如,让我们拿一个包含主机名和有关每个主机的一些信息的文本文件,其中有很多我不关心的垃圾。

Host: foo1
some junk, doesnt matter
some junk, doesnt matter
Info: about foo1 that I really care about!!
some junk, doesnt matter
some junk, doesnt matter
Info: a second line about foo1 that I really care about!!
some junk, doesnt matter
some junk, doesnt matter
Host: foo2
some junk, doesnt matter
Info: about foo2 that I really care about!!
some junk, doesnt matter
some junk, doesnt matter

对我来说,使用 awk 脚本来获取包含主机名和相应行的数据info比使用 sed 所能做的要多一些:

sed -n '/Host:/{h}; /Info/{x;p;x;p;}' myfile.txt

输出如下:

Host: foo1
Info: about foo1 that I really care about!!
Host: foo1
Info: a second line about foo1 that I really care about!!
Host: foo2
Info: about foo2 that I really care about!!

(请注意,Host: foo1在输出中出现了两次。)

解释:

  1. -n禁用输出,除非明确打印

  2. 第一个匹配,找到并将该Host:行放入保持缓冲区 (h)

  3. 第二次匹配,找到下一个 Info: 行,但首先将模式缓冲区中的当前行与保持缓冲区交换(x),并打印(p)该Host:行,然后重新交换(x)并打印(p)Info: 行。

是的,这是一个过于简单的例子,但我怀疑这是一个常见问题,只需使用简单的 sed 单行命令即可快速解决。对于更复杂的任务(例如,您不能依赖给定的可预测序列的任务),awk 可能更适合。

解决方案 3:

虽然@January的回答和例子都很好,但对我来说解释得还不够。我不得不搜索和学习很多东西,直到我设法理解它到底是如何sed -n '1!G;h;$p'工作的。所以我想为像我这样的人详细说明一下这个命令。

首先,让我们看看该命令的作用。

$ echo {a..d} | tr ' ' '
' # Prints from 'a' to 'd' in each line
a
b
c
d
$ echo {a..d} | tr ' ' '
' | sed -n '1!G;h;$p'
d
c
b
a

它像命令一样反转输入tac

sed逐行读取,因此让我们看看每行模式空间保持空间上发生了什么。当h命令将模式空间的内容复制到保持空间时,两个空间都具有相同的文本。

Read line    Pattern Space / Hold Space    Command executed
-----------------------------------------------------------
a            a$                            h
b            b
a$                         1!G;h
c            c
b
a$                      1!G;h
d            d
c
b
a$                   1!G;h;$p

在最后一行,$p打印`d
c
b
a$`格式为

d
c
b
a

如果想要查看每行的模式空间,可以添加一个l命令。

$ echo {a..d} | tr ' ' '
' | sed -n '1!G;h;l;$p'
a$
b
a$
c
b
a$
d
c
b
a$
d
c
b
a

我发现观看这个视频教程《了解 sed 的工作原理》非常有帮助,因为这个家伙一步一步地展示了如何使用每个空格。第 4 个教程中提到了保持空格,但如果您不熟悉,我建议您观看所有视频sed

GNU sed 文档和Bruce Barnett 的 Sed 教程也是非常好的参考资料。

解决方案 4:

这是我今天刚遇到的一个现实问题的简单示例。我有一个数据库转储文件,该文件为制表符分隔值文件,每行一条记录,字段用双引号括起来,字段之间用制表符分隔。

不幸的是,转储中的某些文本字段嵌入了回车符,这导致我导入这些 TSV 文件的数据库失败。回车符行总是看起来像这样:

"60888" "1" "characters"    "JLA [Aquaman; Aztek; Flash [Wally West]; Green Arrow [Connor Hawke]; Green Lantern [Kyle Rayner]; Martian Manhunter; Superman [Clark Kent; Kal-El]];^M
Jemm Son of Saturn; Metron; Plastic Man; Robin [Tim Drake];^M
Injustice Gang [Circe; Doctor Light [Arthur Light]; Joker; Lex Luthor; Mirror Master [Evan McCulloch]; Ocean Master]"

^M显示回车符的位置。)

使用这个简单的 sed 脚本,我能够连接各行并删除回车符:

/
/s/
//g
/[^"]$/{
    H;
    s/
/ /g;
}
/"$/{
    H;
    s/^.*$//;
    x;
    s/
//g;
    p;
}

我尝试了“只使用 awk”的建议,当我想“这实际上比使用保持缓冲区更复杂”时,我已经对脚本有了一点了解。

相关推荐
  为什么项目管理通常仍然耗时且低效?您是否还在反复更新电子表格、淹没在便利贴中并参加每周更新会议?这确实是耗费时间和精力。借助软件工具的帮助,您可以一目了然地全面了解您的项目。如今,国内外有足够多优秀的项目管理软件可以帮助您掌控每个项目。什么是项目管理软件?项目管理软件是广泛行业用于项目规划、资源分配和调度的软件。它使项...
项目管理软件   601  
  华为IPD与传统研发模式的8大差异在快速变化的商业环境中,产品研发模式的选择直接决定了企业的市场响应速度和竞争力。华为作为全球领先的通信技术解决方案供应商,其成功在很大程度上得益于对产品研发模式的持续创新。华为引入并深度定制的集成产品开发(IPD)体系,相较于传统的研发模式,展现出了显著的差异和优势。本文将详细探讨华为...
IPD流程是谁发明的   7  
  如何通过IPD流程缩短产品上市时间?在快速变化的市场环境中,产品上市时间成为企业竞争力的关键因素之一。集成产品开发(IPD, Integrated Product Development)作为一种先进的产品研发管理方法,通过其结构化的流程设计和跨部门协作机制,显著缩短了产品上市时间,提高了市场响应速度。本文将深入探讨如...
华为IPD流程   9  
  在项目管理领域,IPD(Integrated Product Development,集成产品开发)流程图是连接创意、设计与市场成功的桥梁。它不仅是一个视觉工具,更是一种战略思维方式的体现,帮助团队高效协同,确保产品按时、按质、按量推向市场。尽管IPD流程图可能初看之下显得错综复杂,但只需掌握几个关键点,你便能轻松驾驭...
IPD开发流程管理   8  
  在项目管理领域,集成产品开发(IPD)流程被视为提升产品上市速度、增强团队协作与创新能力的重要工具。然而,尽管IPD流程拥有诸多优势,其实施过程中仍可能遭遇多种挑战,导致项目失败。本文旨在深入探讨八个常见的IPD流程失败原因,并提出相应的解决方法,以帮助项目管理者规避风险,确保项目成功。缺乏明确的项目目标与战略对齐IP...
IPD流程图   8  
热门文章
项目管理软件有哪些?
云禅道AD
禅道项目管理软件

云端的项目管理软件

尊享禅道项目软件收费版功能

无需维护,随时随地协同办公

内置subversion和git源码管理

每天备份,随时转为私有部署

免费试用