【问题标题】:command D in sed - output seems different from what the manual sayssed 中的命令 D - 输出似乎与手册所说的不同
【发布时间】:2019-11-05 15:04:13
【问题描述】:

在 sed 手册中找到以下关于命令 D,

D - 如果模式空间不包含换行符,则开始一个正常的新循环,就像发出了 d 命令一样。否则,删除模式空间中的文本直到第一个换行符,并使用生成的模式空间重新开始循环,而不读取新的输入行

但我尝试的示例似乎与上面描述的不匹配。

$cat test
LINE 101
LINE 201
LINE 301
LINE 401

$ sed -nr '1{p;N;p;D;}' test
LINE 101
LINE 101
LINE 201

我根据sed手册描述理解的方式如下,

  1. 打印模式空间(第 101 行)
  2. 将 LINE 201 附加到模式空间打印模式空间 (LINE 101 \n LINE 201)
  3. 删除模式空间中的第一条新行。图案 空间现在将有 LINE 201
  4. 现在 sed 手册说“并使用生成的模式空间重新启动循环,而不读取新的输入行” - 这是否意味着回到命令的开头?如果是这样的话,那么我们应该有一个输出 - LINE 201, LINE 201 \n LINE 301 和这样的循环直到结束。

但这不是我看到的输出。

【问题讨论】:

  • 不完全清楚您期望什么输出,但您使用的是 'n' 选项,它将抑制所有输出 - 除非在第一个循环中,当您明确要求它时。跨度>
  • 在您的示例中有 4 行。循环结束时自动打印一行被关闭 (-n),命令被地址1 限制在第一行。打印第一行 (p) 并附加第二行 (N)。再次打印第 1 行和第 2 行 (p) 并删除第一行。没有进行进一步的处理,因为当前行号现在是 2 或更多。顺便说一句,-r 选项不是必需的,因为不存在正则表达式。
  • 我故意打开 -n 标志来抑制默认回显。我的观点是输出与手册页所说的 D 将执行的操作不匹配,“删除模式空间中的文本直到第一个换行符,并使用生成的模式空间重新启动循环,而不读取新的输入行”。由于显然它没有读取新的输入行 1{ } 不应该让它停止。因为我正在测试,所以我把 -r 留在了那里。在我正在查看的一些代码中看到了 D 的用法,并想知道 D 究竟是如何工作的。
  • 处理完第一个循环后,sed 的行号为 2。虽然模式空间仍包含LINE 201,但处理仅限于地址/行号 1。关闭自动打印, 将不再进行打印。尝试删除第 1 行地址,即sed -n 'p;N;p;D' file。这将打印第 1 行,然后打印 1 和 2、2、2 和 3、3、3 和 4、4,然后 N 将尝试读取 eof 并终止。
  • 我得到了答案……在 Daniel Goldman 关于 sed 的书中看到了这一点。 “sed 维护一个行计数器.... n 和 N 命令增加行计数器”。这就解释了

标签: sed


【解决方案1】:

我认为答案已经包含在@potong 的评论中。

关于为什么OP对sed的行为感到惊讶,我只能推测这是由于他的第2点的措辞:

将第 201 行追加到模式空间打印模式空间(第 101 行 \n 第 201 行)

这为以下错误解释留下了空间:

N 选择输入的下一行并将其附加到当前 模式空间(中间有换行符);那么,当结束时 到达脚本,同样的下一行输入是 read

这意味着LINE 201 被处理了两次。相反,它只被处理一次,因为N 读取新的一行输入并将其追加到模式空间的内容中。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-06-14
    • 1970-01-01
    • 2012-01-04
    • 1970-01-01
    • 2014-10-23
    • 2012-01-10
    相关资源
    最近更新 更多