【问题标题】:Require exactly 1 trailing newline in a file文件中恰好需要 1 个尾随换行符
【发布时间】:2017-01-25 05:37:57
【问题描述】:

我有各种使用尾随换行方式的文件。没有回车,只有\n。有些文件有多个换行符,有些文件没有尾随换行符。我想就地编辑文件。

如何将文件编辑为正好有 1 个尾随换行符?

【问题讨论】:

  • 没有 UNIX 工具可以进行真正的“就地”编辑,它们都创建一个临时文件(或 ed 的内部缓冲区)并用它覆盖原始文件。有问题吗?
  • 不,临时文件只要是透明的就可以。我不想处理备份文件。

标签: perl unix awk sed


【解决方案1】:

将文本文件就地更改为只有一个尾随换行符:

 sed -zi 's/\n*$/\n/'

这需要 GNU sed。

-z 告诉 sed 使用 NUL 字符作为分隔符读入文件。由于文本文件没有 NUL 字符,因此具有一次读取整个文件的效果。

-i 告诉 GNU sed 更改文件。

s/\n*$/\n/ 告诉 sed 用一个换行符替换文件末尾的许多换行符。

【讨论】:

  • 但是如果文件末尾没有\n,则不会添加一个
  • @harmic 是的,它会的。因为\n* 匹配 个或多个换行符,所以即使不存在,该命令也会添加一个。是什么让你不这样说?
【解决方案2】:

用一个替换所有尾随的新行?

$text =~ s/\n+$/\n/;

这会在文件末尾留下一个换行符——如果它至少有一个换行符开始的话。如果即使文件没有文件也希望它存在,请将\n+ 替换为\n*

对于就地规范,暗示一个单行:

perl -i -0777 -wpe 's/\n+$/\n/' file.txt

开关的含义在Command Switches in perlrun 中解释。


这里是开关的摘要。请参阅上述文档以获得准确的解释。

  • -i“就地”更改文件。请注意,仍然会复制数据并使用临时文件

  • -0777 读取整个文件。 -0[oct|hex]$/ 设置为数字,因此使用 -0 设置为 nul

  • -w 使用警告。与use warnings 不完全相同,但总比没有好

  • -p''中的代码依次运行在文件的每一行,如-n,然后打印$_

  • -e'' 之间的后面的内容作为 Perl 代码执行
    -E 是一样的,但也启用features,如say

请注意,我们可以通过使用核心OB::Deparse 模块来查看等效代码

perl -MO=Deparse -wp -e 1

打印出来

BEGIN { $^W = 1; }
LINE: while (defined($_ = <ARGV>)) {
    '???';
}
continue {
    print $_;
}
-e syntax OK

-w-p 显示一个等效于一行的脚本。

【讨论】:

    【解决方案3】:
    perl -i -0 -pe 's/\n\n*$/\n/' input-file
    

    【讨论】:

      【解决方案4】:

      到目前为止发布的解决方案会将您的整个输入文件读入内存,如果您的文件很大,这将是一个问题。这只会将连续的空行读入内存:

      awk -i inplace '/./{printf "%s", buf; buf=""; print; next} {buf = buf $0 ORS}' file
      

      以上使用 GNU awk 进行就地编辑。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2017-05-06
        • 2021-07-26
        • 1970-01-01
        • 2016-10-14
        相关资源
        最近更新 更多