了解sed hold-space工作流程

时间:2014-05-28 10:03:05

标签: 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的工作流程。

6 个答案:

答案 0 :(得分:7)

你几乎拥有它。以下是您的脚本所做的事情:

/[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

答案 1 :(得分:2)

我无法帮助您使用sed版本,但awk解决方案可以轻松完成。

awk '/[0-9]+/ {f=$0} END {print f}' file
hippo 9991

答案 2 :(得分:2)

这可能适合你(GNU sed):

sed '/[0-9]/h;$!d;x' file

如果一行包含一个数字,则将其移动到保留空间中(以前的线路将被覆盖!)。除最后一行之外的所有行都删除(删除的行永远不会被打印)。在最后一行交换到保留空间。程序的自然流程打印包含数字的最后一行,不需要选项。

答案 3 :(得分:1)

以下适用于我:

sed -n -r '/[0-9]+/ {h;x}; ${x;p}'

您希望仅在存在整数的情况下同时运行hx,在您的示例中,每次都会运行x。最后,您不想打印最后一行,而是打印最后一行,因此您必须再次交换它们。

答案 4 :(得分:0)

我愿意:

 sed -n -r '/[0-9]+/{h}; ${x;p}' file 

h用当前(匹配)行覆盖保留空间 当到最后一行($)时,我们(x)交换模式/保持空间,并打印保持位置的内容,这将是模式的最后一个匹配行{{1} }。

答案 5 :(得分:0)

SELECT 
    employee_id,
    department_id,
    salary,
    (
        select min(EMPLOYEES.salary) 
        from HR.EMPLOYEES E 
        where department_id = EMPLOYEES.department_id
    )
from HR.EMPLOYEES;

缺点是我们不了解“ sed”,但要简单得多。