sed - 了解 sed 保持空间工作流程

标签 sed

我想打印出包含一个或多个整数的文件的最后一行。下例中的“Hippo 9991”。我试图用 gsed -n -r '/[0-9]+/h;x;$p' 命令来实现这一点,但这并不奏效:

$ cat testfile 
dog
lion 34
elephant
tiger 7
hippo 9991
zebra
gepard
cat
$ cat testfile | gsed -n -r '/[0-9]+/h;x;$p'
gepard
$ 

有人能解释一下 gsed -n -r '/[0-9]+/h;x;$p' 到底是做什么的吗?据我了解,它应该从行中删除尾随的换行符并将该行读入模式空间。然后,如果模式空间中的行包含一个或多个整数,则通过替换保持空间中的前一个数据将该行放入保持空间。重复此循环,直到将打印的最后一行。显然我没有正确理解这一点。不仅仅是一个正确的答案,我想了解 sed 的工作流程。

最佳答案

你几乎拥有它。这是您的脚本的作用:

/[0-9]+/h     # if line contains a number, save the line to hold space
x             # swap content of pattern space and hold space
$p            # when on the last line print pattern space

您保存该行以保留空间,然后将其交换回模式空间。模式空间和保持空间的内容可以这样表示:
Line      Command     Pattern Space       Hold Space
~~~~    ~~~~~~~~~~~   ~~~~~~~~~~~~~       ~~~~~~~~~~
 1       /[0-9]+/h     dog                   
 1           x                             dog                 
 2       /[0-9]+/h     lion 34             lion 34
 2           x         lion 34             lion 34
 3       /[0-9]+/h     elephant            lion 34
 3           x         lion 34             elephant
 4       /[0-9]+/h     tiger 7             tiger 7
 4           x         tiger 7             tiger 7
 .
 .
 .
 $       /[0-9]+/h     cat                 geopard
 $           x         geopard             cat
 $           p         geopard             cat

您真正想要的是仅在到达输入文件的最后一行时交换内容。您可以通过对 xp 命令进行分组来做到这一点:
gsed -n -r '/[0-9]+/h; $ {x;p}' testfile

输出:
hippo 9991

对应的模式空间和保持空间序列现在是:
Line      Command     Pattern Space       Hold Space
~~~~    ~~~~~~~~~~~   ~~~~~~~~~~~~~       ~~~~~~~~~~
 1       /[0-9]+/h     dog                   
 2       /[0-9]+/h     lion 34             lion 34
 3       /[0-9]+/h     elephant            lion 34
 4       /[0-9]+/h     tiger 7             tiger 7
 .
 .
 .
 $       /[0-9]+/h     cat                 hippo 9991
 $           x         hippo 9991          cat
 $           p         hippo 9991          cat

关于sed - 了解 sed 保持空间工作流程,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23908561/

相关文章:

bash - 解析变更日志并提取版本的变更

regex - 使用sed删除不匹配的部分

bash - 在/etc/hosts 文件中添加行

variables - sed with & in 变量

sed - 基于文件中第一个字段的唯一行数

linux - 如何按分隔列将文本文件逐行拆分为 2 个文本文件?

bash - sed:用文件内容替换一系列文本

linux - 如何删除 BASH 中的一行?

bash - 一行中 bash 脚本中的文件扩展名列表

regex - 如何跳过类似 perl sed 的查找/替换命令中的不匹配项?