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

2024-11-05 08:37:00
admin
原创
163
摘要:问题描述:我对 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”的建议,当我想“这实际上比使用保持缓冲区更复杂”时,我已经对脚本有了一点了解。

相关推荐
  政府信创国产化的10大政策解读一、信创国产化的背景与意义信创国产化,即信息技术应用创新国产化,是当前中国信息技术领域的一个重要发展方向。其核心在于通过自主研发和创新,实现信息技术应用的自主可控,减少对外部技术的依赖,并规避潜在的技术制裁和风险。随着全球信息技术竞争的加剧,以及某些国家对中国在科技领域的打压,信创国产化显...
工程项目管理   1565  
  为什么项目管理通常仍然耗时且低效?您是否还在反复更新电子表格、淹没在便利贴中并参加每周更新会议?这确实是耗费时间和精力。借助软件工具的帮助,您可以一目了然地全面了解您的项目。如今,国内外有足够多优秀的项目管理软件可以帮助您掌控每个项目。什么是项目管理软件?项目管理软件是广泛行业用于项目规划、资源分配和调度的软件。它使项...
项目管理软件   1354  
  信创国产芯片作为信息技术创新的核心领域,对于推动国家自主可控生态建设具有至关重要的意义。在全球科技竞争日益激烈的背景下,实现信息技术的自主可控,摆脱对国外技术的依赖,已成为保障国家信息安全和产业可持续发展的关键。国产芯片作为信创产业的基石,其发展水平直接影响着整个信创生态的构建与完善。通过不断提升国产芯片的技术实力、产...
国产信创系统   21  
  信创生态建设旨在实现信息技术领域的自主创新和安全可控,涵盖了从硬件到软件的全产业链。随着数字化转型的加速,信创生态建设的重要性日益凸显,它不仅关乎国家的信息安全,更是推动产业升级和经济高质量发展的关键力量。然而,在推进信创生态建设的过程中,面临着诸多复杂且严峻的挑战,需要深入剖析并寻找切实可行的解决方案。技术创新难题技...
信创操作系统   27  
  信创产业作为国家信息技术创新发展的重要领域,对于保障国家信息安全、推动产业升级具有关键意义。而国产芯片作为信创产业的核心基石,其研发进展备受关注。在信创国产芯片的研发征程中,面临着诸多复杂且艰巨的难点,这些难点犹如一道道关卡,阻碍着国产芯片的快速发展。然而,科研人员和相关企业并未退缩,积极探索并提出了一系列切实可行的解...
国产化替代产品目录   28  
热门文章
项目管理软件有哪些?
云禅道AD
禅道项目管理软件

云端的项目管理软件

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

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

内置subversion和git源码管理

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

免费试用