如何删除sed创建的EOF空行 [英] How to remove EOF empty line created by sed

查看:94
本文介绍了如何删除sed创建的EOF空行的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I'm using sed to modify the first part of a text file. The problem is that sed automatically introduces a empty line at the end of the file.

您知道如何解决吗?(不使用截断,因为我不想在MacOS中安装其他软件)

Do you know how to solve that? (Not using truncate, as I do not want to install additional software in MacOS)

谢谢!

推荐答案

您的问题的快速答案是将您的输出通过管道传输到另一个 cmd :

A quick answer to your question would be to pipe your output to another cmd like awk:

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

这将删除最后一个< newline> .这不能通过 sed 完成,下面的答案试图对其进行解释.可以在

This will remove the last <newline>. This cannot be done by sed, the answer below tries to explain it. More possibilities can be found in How can I delete a newline if it is the last character in a file?

为什么 sed 总是以< newline> 结尾?该问题的答案取决于标准的解释和您使用的 sed 的实现.

Why does sed always finishes with a <newline>? The answer to this question depends on the interpretation of the standard and the implementation of sed you use.

根据 sed posix标准:

According to the sed posix standard:

在默认操作中, sed 应该周期性地添加一行输入,减去其终止< newline> 字符,进入模式空间.如果在模式中使用< newline> ,则应跳过从输入中读取内容的操作在 D 命令之前的空格之前结束.sed实用程序然后应依次应用其地址选择的所有命令模式空间,直到命令开始下一个周期或退出为止.如果不命令显式开始一个新的周期,然后在脚本结尾模式空间应复制到标准输出( -n 除外)指定),并删除模式空间.每当模式空间写入标准输出或命名文件, sed 应立即使用< newline> .

In default operation, sed cyclically shall append a line of input, less its terminating <newline> character, into the pattern space. Reading from input shall be skipped if a <newline> was in the pattern space prior to a D command ending the previous cycle. The sed utility shall then apply in sequence all commands whose addresses select that pattern space, until a command starts the next cycle or quits. If no commands explicitly started a new cycle, then at the end of the script the pattern space shall be copied to standard output (except when -n is specified) and the pattern space shall be deleted. Whenever the pattern space is written to standard output or a named file, sed shall immediately follow it with a <newline>.

这意味着两件事:

  • 如果某行未由< newline> 终止,则不会进行处理.
  • 任何写入标准输出的内容都以< newline> 终止,即,由于命令周期结束或发出命令 p 而输出或 P .
  • a line is not processed if it is not terminated by a <newline>.
  • anything written to standard output is terminated with a <newline>, i.e. output as a result of the end of the command cycle, or the issuing of commands p or P.

示例: 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> 会添加到任何输出.

There is clearly no processing if the lines that are not terminated by a <newline>. Otherwise <newlines> are added at any output.

MacOS sed 手册的含义与posix相似.

The MacOS sed manual has a similar interpration as posix.

通常, sed 循环复制一行输入,但不包括输入终止换行符,模式空间(除非 D 函数后面有剩余),将应用所有命令使用选择该模式空间的地址,将模式空间复制到标准输出,附加换行,并删除模式空间.

Normally, sed cyclically copies a line of input, not including its terminating newline character, into a pattern space, (unless there is something left after a D function), applies all of the commands with addresses that select that pattern space, copies the pattern space to the standard output, append-ing appending ing a newline, and deletes the pattern space.

这没有经过测试,因为我没有Mac.

This is not tested as I do not have a mac.

GNU sed 手册对此问题的看法似乎略有不同:

The GNU sed manual seems to have a slightly different perspective on the matter:

sed 通过在输入的每一行上执行以下循环来进行操作:首先,sed从输入流中读取一行,删除所有结尾换行符,并将其放在模式空间中.然后命令是被执行每个命令可以有一个与之关联的地址:addresss是一种条件代码,只有在以下情况下才执行命令:在执行命令之前先验证条件.

sed operates by performing the following cycle on each line of input: first, sed reads one line from the input stream, removes any trailing newline, and places it in the pattern space. Then commands are executed; each command can have an address associated to it: addresses are a kind of condition code, and a command is only executed if the condition is verified before the command is to be executed.

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

When the end of the script is reached, unless the -n option is in use, the contents of pattern space are printed out to the output stream, adding back the trailing newline if it was removed.

以下含义:

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

示例: sed(GNU sed)4.2.2

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

In the following example, a newline is only added after p and not after the end of the cycle. (newline is 012 in hex)

    $ 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

脚注7 对此进行了解释:

实际上,如果 sed 打印的行没有终止的换行符,尽管如此,只要有更多文字,就会打印出缺少的换行符发送到相同的输出流,这给出了最不期望的惊喜",即使它不会发出 sed -n p 之类的命令与 cat 完全相同.

Actually, if sed prints a line without the terminating newline, it will nevertheless print the missing newline as soon as more text is sent to the same output stream, which gives the "least expected surprise" even though it does not make commands like sed -n p exactly identical to cat.

结论:根据 posix标准,您总是会得到一个以< newline> 结尾的输出文件,但是它可能不是输入的最后一行.根据 Gnu手册,您的输出将以输入文件结尾处的内容与您相同.

In conclusion: according to the posix standard, you will always end up with an output file finishing with a <newline>, it might however not be the last line of the input. According the the Gnu manual, your output terminates with the same amount of you have at the end of your input file.

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

Question: is GNU's sed --posix real posix?

这篇关于如何删除sed创建的EOF空行的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆