How can I delete a trailing newline in bash?
You can use perl
without 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
But why not use chomp
itself:
$ printf "one\ntwo\n" | perl -pe 'chomp if eof'; echo " done"
This should work:
printf "one\ntwo\n" | awk 'NR>1{print PREV} {PREV=$0} END{printf("%s",$0)}' ; echo " done"
The script always prints previous line instead of current, and the last line is treated differently.
What it does in more detail:
NR>1{print PREV}
Print previous line (except the first time).{PREV=$0}
Stores current line inPREV
variable.END{printf("%s",$0)}
Finally, print last line withtout line break.
Also note this would remove at most one empty line at the end (no support for removing "one\ntwo\n\n\n"
).
If you want an exact equivalent to chomp
, the first method that comes to my mind is the awk solution that LatinSuD already posted. I'll add some other methods that don't implement chomp
but implement some common tasks that chomp
is often used for.
When you stuff some text into a variable, all newlines at the end are stripped. So all these commands produce the same single-line output:
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"
If you want to append some text to the last line of a file or of a command's output, sed
can be convenient. With GNU sed and most other modern implementations, this works even if the input doesn't end in a newline¹; however, this won't add a newline if there wasn't one already.
sed '$ s/$/ done/'
¹ However this doesn't work with all sed implementations: sed is a text processing tool, and a file that isn't empty and doesn't end with a newline character is not a text file.