为什么会产生这些结果?
C:\>(echo a && echo b) | sed "1!G;h;$p"
a
b
a
b
a
C:\>
Added-
我现在看到毫无疑问,它会给出那些结果......但是
(补充说明 - 第2行=最后一行。但是我看到你写了最后一行,强调它是$匹配第二行作为最后一行。我接受那个符号。另外,第1行,第2行,最后一行,参考到输入线。)
乔纳森,你写了
a - 第1行,图案空间
b - 第2行,图案空间,第1行
a - 第2行,图案空间,第2行
b - 最后一行,$ p模式空间,第1行
a - 最后一行,$ p模式空间,第2行
但不是吗 注意 - 丹尼斯的评论已经证实“但不会是这样”是正确的
a - 第1行,图案空间
b - 最后一行,$ p模式空间,第1行
a - 最后一行,$ p模式空间,第2行
b - 第2行,图案空间,第1行
a - 第2行,模式空间,第2行
即。相同的输出
一个
b
一个
b
但是关于如何做b a的描述是另一种方式
假设$操作在最后一行,而不是在它之后......
但是你所写的内容让它看起来像是在它之后操作。
答案 0 :(得分:3)
1!G
将保留空间附加到第一行之后的模式空间。h
将模式空间复制到保留空间(每行)。$p
打印最后一行(再次)。第一个输入行是'a'; G命令被忽略;该行被复制到保留空间;该行已打印(因为您没有说-n
)。
第二个输入行是'b'; G命令将保持空间('a')附加到模式空间('b'); 'h'命令将模式空间复制到保留空间;由于'no -n
',模式空间会被打印一次。
没有更多输入,因此$p
会动作并打印模式空间。
所以,你得到:
a
- 第1行,模式空间b
- 第二行,模式空间,第1行a
- 第二行,模式空间,第2行b
- 最后一行,$ p模式空间,第1行a
- 最后一行,$ p模式空间,第2行问的问题是:我是否向后标记了'b / a'线对?
好问题:不确定......我们怎么知道?
让我们在'$'集合中添加另一个操作:
(echo a; echo b) | sed -e '1!G;h;$p;$s/b\na/X'
输出结果为:
a
b
a
X
表明$p
打印确实发生在$s///
操作之前,该操作发生在最终打印模式空间之前。
这一观察的一个副作用让我感到惊讶(但在反思时才有意义),sed
知道它在处理最后一行的时间,因为它在最后一行上运行脚本。这意味着它在换行符之后执行预读,以查看是否有更多数据要提取。 Dennis Williamson显示第928行的sed source包含一个函数test_eof()
,它确实可以执行前瞻性的一个字符。
(关于SO的一个好处是,即使你教书,你也要学习!)
所以,令我惊讶的是,似乎 sed
知道它何时到达最后一行才能处理它 - 所以它似乎做了某种预读。无论是那个还是我误解了一些非常糟糕的事情,或者为时已晚,我需要去睡觉。
答案 1 :(得分:0)
第一行输入是'a' 第二行输入是'b'
Sed将输入的第一行(a)读入模式空间并运行命令。这些命令中有三个。 1!G被跳过,因为只有当它不是第一行时才适用(将图案空间附加到保持空间)。 h将图案空间复制到容纳空间。 $ p不适用。然后在运行命令后打印模式空间。它打印'a'。请注意,保持空间仍为“a”,即使在将下一行读入模式空间后也是如此。模式空间当前是'a',但在读入下一行时会改变 - 被覆盖。
Sed将第二行输入(b)读入模式空间,注意保持空间仍为“a”。然后运行1!G将保持空间(a)附加到图案空间(b),给出'b \ na'的图案空间和'a'的保持空间。下一个命令是'h',它将模式空间(b \ na)复制到保留空间,给出一个'b \ na'的保留空间,尽管我们看到这里的保持空间不相关。下一个命令是$ p,因为第二行输入(我们输入的输入行)也是最后一行输入,所以如上所述,$ p适用并打印模式空间,所以我们得到b \ na印刷。然后再次打印图案空间,因为与第一行一样,在运行所有命令后,将打印图案空间。因此,读取第二行输入(这是输入的最后一行),我们得到b \ na并再次b \ na。 b \ na的第一次出现来自$ p,第二次出现是在所有命令运行后出现的模式空间的打印。
a <------- Reading first line of input. Printing the pattern space that happens after the end of the commands.
b\na <---- Reading second line of input(which is the last line of input), hitting the $p command. That command didn't apply in the case of the first line of input.
b\na <--- Still on the second line of input(which is the last line of input), printing the pattern space that happens after the end of the commands.
(注意,有人可能会问......如果它是\ n,并且b \ na \ nie不应该在模式空间的末尾有一个新的行字符,因为它们是行...并且* nix使用\ n作为行终止符而不是行分隔符。也许..但我认为在sed模式空间的情况下它可能最后没有\ n。我在sed手册中读到了append命令的工作原理,如果他们要将'text'附加到模式空间或持有空间,他们会附加一个\ n后跟那个'text'。所以这表明模式空间不会以\ n结尾但是我不是专家)