理解sed保持空间工作流程
我想打印出包含一个或多个整数的文件的最后一行。“Hippo 9991”在下面的示例中。我试图通过理解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$
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的工作流程。我无法帮助您使用
sed
版本,但是awk
解决方案可以轻松做到这一点
awk '/[0-9]+/ {f=$0} END {print f}' file
hippo 9991
以下是我的作品:
sed -n -r '/[0-9]+/ {h;x}; ${x;p}'
仅当整数存在时,才希望同时运行
h
和x
,在您的示例中,每次运行x
。最后,您不想打印最后一行,而是要打印最后存储的行,因此您必须再次交换它们。您几乎拥有了它。以下是脚本的作用:
/[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
您真正想要的是仅在到达输入文件的最后一行时交换内容。您可以通过将x
和p
命令分组来执行此操作:
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 -n -r '/[0-9]+/{h}; ${x;p}' file
h
用当前(匹配)行覆盖保留空间
当直到最后一行($
)时,我们(x
)交换图案/保留空间,并打印保留位置的内容,这将是图案的最后匹配行[0-9]+
,这可能适用于您(GNU-sed):
如果一行包含一个数字,则将其移入保留空间(以前移入的行将被覆盖!)。除最后一行之外的所有行都被删除(删除的行永远无法打印)。在最后一行上,交换到保留空间。程序的自然流程打印包含数字的最后一行,无需选择
grep [0-9] testfile | tail -1
缺点是我们无法了解“sed”,但要简单得多。谢谢您的解释!难道不可能进一步简化这个问题,比如
gsed-n-r'/[0-9]+//h${x;p}'
?这将在每一行包含整数时覆盖保留空间,一旦到达最后一行,它将用保留空间交换图案空间并打印。@Martin:是的,似乎有效(针对文件测试,搜索的行在末尾和中间)。
grep [0-9] testfile | tail -1