如何删除 bash 中的尾随换行符?

如何删除 bash 中的尾随换行符?

我正在寻找行为类似于 Perl 的东西chomp。我正在寻找一个简单地打印其输入的命令,如果它是换行符,则减去最后一个字符:

$ printf "one\ntwo\n" | COMMAND_IM_LOOKING_FOR ; echo " done"
one
two done
$ printf "one\ntwo" | COMMAND_IM_LOOKING_FOR ; echo " done"
one
two done

(Bash 和 Zsh 中的命令替换会删除所有尾随新行,但我正在寻找最多删除一个尾随新行的东西。)

答案1

您可以perl不使用chomp

$ printf "one\ntwo\n" | perl -pe 's/\n\z// if eof'; echo " done"
one
two done

$ printf "one\ntwo" | perl -pe 's/\n\z// if eof'; echo " done"
one
two done

但为什么不使用chomp它自己:

$ printf "one\ntwo\n" | perl -pe 'chomp if eof'; echo " done"

答案2

这应该有效:

printf "one\ntwo\n" | awk 'NR>1{print PREV} {PREV=$0} END{printf("%s",$0)}' ; echo " done"

该脚本始终打印上一行而不是当前行,并且最后一行的处理方式有所不同。

更详细地讲它是做什么的:

  1. NR>1{print PREV}打印上一行(第一次除外)。
  2. {PREV=$0}将当前行存储在PREV变量中。
  3. END{printf("%s",$0)}最后,打印最后一行,不换行。

另请注意,这最多会删除末尾的一个空行(不支持删除"one\ntwo\n\n\n")。

答案3

如果你想要一个完全等价的方法chomp,我想到的第一个方法是LatinSuD 已经发布的 awk 解决方案。我将添加一些其他方法,这些方法不实现但实现一些经常使用的chomp常见任务。chomp

当您将一些文本填充到变量中时,末尾的所有换行符都会被删除。因此所有这些命令都会产生相同的单行输出:

echo "$(printf 'one\ntwo') done"
echo "$(printf 'one\ntwo\n') done"
echo "$(printf 'one\ntwo\n\n') done"
echo "$(printf 'one\ntwo\n\n\n\n\n\n\n\n\n\n') done"

如果您想将一些文本附加到文件或命令输出的最后一行,这sed会很方便。对于 GNU sed 和大多数其他现代实现,即使输入不以换行符结束,这也可以工作;但是,如果还没有换行符,则不会添加换行符。

sed '$ s/$/ done/'

1然而,这并不适用于所有 sed 实现:sed 是一种文本处理工具,非空且不以换行符结尾的文件不是文本文件。

答案4

另一种perl方法。这会将整个输入读取到内存中,因此对于大量数据来说这可能不是一个好主意(使用 cuonglm 或awk该方法):

$ printf "one\ntwo\n" | perl -0777pe 's/\n$//'; echo " done"
one
two done

相关内容