【问题标题】:How to remove EOF empty line created by sed [duplicate]如何删除由 sed 创建的 EOF 空行 [重复]
【发布时间】:2018-08-29 02:51:54
【问题描述】:

我正在使用 sed 修改文本文件的第一部分。问题是 sed 会在文件末尾自动引入一个空行。

你知道怎么解决吗? (不使用截断,因为我不想在 MacOS 中安装额外的软件)

谢谢!!

【问题讨论】:

  • 请在您的帖子中的代码标签中向我们展示示例输入和示例输出。
  • Sed 引入 EOF 空行无论如何你都使用它@RavinderSingh13
  • @MMManuel 我稍微更新了我的答案,我希望它能解释它并告诉你如何实现你的目标。

标签: bash macos awk sed scripting


【解决方案1】:

对您的问题的快速回答是将您的输出通过管道传输到另一个 cmd,例如 awk

sed 'commands' file | awk '(NR>1){printf "%s\n",l}{l=$0}END{printf "%s",l}'

这将删除最后一个<newline>sed 无法做到这一点,下面的答案试图解释它。更多可能性可以在How can I delete a newline if it is the last character in a file?找到

为什么sed 总是以<newline> 结尾? 这个问题的答案取决于对标准的解释以及你使用的sed的实现。

根据sed posix standard

在默认操作中,sed 会循环追加一行输入, 减去它的终止 <newline> 字符,进入模式空间。 如果 <newline> 在模式中,则应跳过从输入中读取 D 命令结束前一个循环之前的空间。 sed 实用程序 然后应按顺序应用其地址选择的所有命令 模式空间,直到命令开始下一个循环或退出。如果不 命令明确地开始一个新的循环,然后在脚本结束时 模式空间应复制到标准输出(-n 除外 已指定)并且应删除模式空间。 每当 模式空间写入标准输出或命名文件,sed 应 立即使用 <newline> 跟随它。

这意味着两件事:

  • 如果一行没有被<newline> 终止,则不会处理该行。
  • 写入标准输出的任何内容都以<newline> 终止,即作为命令周期结束或发出命令pP 的结果输出。

示例:sed (SunOS 5.10) SUNWcsu 11.10.0 rev=2005.01.21.15.53

$ echo -n foo | sed 'p'
$ echo -n 'foo\nbar' | sed 'p'                                                                                                                                                                                                
foo
foo

如果没有以<newline> 终止的行,显然没有处理。否则,<newlines> 将添加到任何输出。

MacOS sed manual 与 posix 有类似的解释。

通常,sed 循环复制一行输入,不包括其 终止换行符,变成 一个模式空间,(除非在 D 函数之后还有一些东西),应用所有的命令 使用选择该模式空间的地址,将模式空间复制到标准输出,追加追加 ing 一个换行符,并删除模式空间。

因为我没有mac,所以没有测试。

GNU sed manual 对此事的看法似乎略有不同:

sed 通过在每一行输入上执行以下循环来运行: 首先,sed 从输入流中读取一行,删除任何尾随 换行符,并将其放置在模式空间中。然后命令是 执行;每个命令都可以有一个与之关联的地址:地址 是一种条件码,一个命令只有在 在执行命令之前验证条件。

当到达脚本末尾时,除非-n 选项正在使用,否则模式空间的内容将打印到输出流中,如果尾随换行符被删除,则将其添加回来。

这意味着以下内容:

  • 所有行都被处理,全部或不被<newline>终止
  • 如果到达命令周期的末尾,则会添加与最初删除相同数量的 <newline>

例如:sed (GNU sed) 4.2.2

在以下示例中,仅在p 之后添加换行符,而不是在循环结束之后。 (换行符是十六进制的012

    $ echo -n foo | hexdump -b
    0000000 146 157 157                                                    
    0000003
    $ echo -n foo | sed --posix 'p' | hexdump -b
    0000000 146 157 157 012 146 157 157                                    
    0000007

这是Footnote 7解释的:

实际上,如果sed 打印出没有终止换行符的行,它 尽管如此,只要有更多文本,就会打印丢失的换行符 发送到相同的输出流,这给出了“最不期望 惊喜”,即使它不会发出像 sed -n p 这样的命令 与cat 完全相同。

结论:根据posix standard,您最终会得到一个以<newline> 结尾的输出文件,但它可能不是输入的最后一行。根据Gnu manual,您的输出以与输入文件末尾相同的数量终止。

问题: GNU 的 sed --posix 是真正的 posix 吗?

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2021-10-11
    • 1970-01-01
    • 2014-01-17
    • 2021-12-13
    • 2022-01-23
    • 1970-01-01
    • 1970-01-01
    • 2019-05-04
    相关资源
    最近更新 更多