为什么这个sed线会这样做?

时间:2011-01-14 00:47:17

标签: sed

为什么会产生这些结果?

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的描述是另一种方式

假设$操作在最后一行,而不是在它之后......

但是你所写的内容让它看起来像是在它之后操作。

2 个答案:

答案 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结尾但是我不是专家)