我正在寻找行为类似于 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"
该脚本始终打印上一行而不是当前行,并且最后一行的处理方式有所不同。
更详细地讲它是做什么的:
NR>1{print PREV}
打印上一行(第一次除外)。{PREV=$0}
将当前行存储在PREV
变量中。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