Fli*_*imm 10 bash shell-script text-processing newlines
我正在寻找行为类似于 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
Run Code Online (Sandbox Code Playgroud)
(Bash 和 Zsh 中的命令替换会删除所有尾随的新行,但我正在寻找最多删除一个尾随新行的东西。)
cuo*_*glm 16
您可以perl不使用chomp:
$ printf "one\ntwo\n" | perl -0 -pe 's/\n\Z//'; echo " done"
one
two done
$ printf "one\ntwo" | perl -0 -pe 's/\n\Z//'; echo " done"
one
two done
Run Code Online (Sandbox Code Playgroud)
但为什么不使用chomp它自己:
$ printf "one\ntwo\n" | perl -pe 'chomp if eof'; echo " done"
Run Code Online (Sandbox Code Playgroud)
Lat*_*SuD 10
这应该有效:
printf "one\ntwo\n" | awk 'NR>1{print PREV} {PREV=$0} END{printf("%s",$0)}' ; echo " done"
Run Code Online (Sandbox Code Playgroud)
脚本总是打印前一行而不是当前行,最后一行的处理方式不同。
它更详细地做什么:
NR>1{print PREV} 打印上一行(第一次除外)。{PREV=$0}将当前行存储在PREV变量中。END{printf("%s",$0)} 最后,打印最后一行而不换行。另请注意,这将在末尾删除最多一个空行(不支持删除"one\ntwo\n\n\n")。
如果您想要完全等同于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"
Run Code Online (Sandbox Code Playgroud)
如果您想将一些文本附加到文件或命令输出的最后一行,sed可以很方便。使用 GNU sed 和大多数其他现代实现,即使输入没有以换行符结尾¹,这也有效;但是,如果还没有换行符,这将不会添加换行符。
sed '$ s/$/ done/'
Run Code Online (Sandbox Code Playgroud)
¹但是,这不适用于所有 sed 实现:sed 是一种文本处理工具,并且非空且不以换行符结尾的文件不是文本文件。