I have some files that I'd like to delete the last newline if it is the last character in a file. od -c
shows me that the command I run does write the file with a trailing new line:
0013600 n t > \n
I've tried a few tricks with sed but the best I could think of isn't doing the trick:
sed -e '$s/\(.*\)\n$/\1/' abc
Any ideas how to do this?
You can do this with
head
from GNU coreutils, it supports arguments that are relative to the end of the file. So to leave off the last byte use:To test for an ending newline you can use
tail
andwc
. The following example saves the result to a temporary file and subsequently overwrites the original:You could also use
sponge
frommoreutils
to do "in-place" editing:You can also make a general reusable function by stuffing this in your
.bashrc
file:Update
As noted by KarlWilbur in the comments and used in Sorentar's answer,
truncate --size=-1
can replacehead -c-1
and supports in-place editing.You can take advantage of the fact that shell command substitutions remove trailing newline characters:
Simple form that works in bash, ksh, zsh:
Portable (POSIX-compliant) alternative (slightly less efficient):
Note:
in.txt
ends with multiple newline characters, the command substitution removes all of them - thanks, @Sparhawk. (It doesn't remove whitespace characters other than trailing newlines.)printf %s
ensures that no newline is appended to the output (it is the POSIX-compliant alternative to the nonstandardecho -n
; see http://pubs.opengroup.org/onlinepubs/009696799/utilities/echo.html and https://unix.stackexchange.com/a/65819)A guide to the other answers:
If Perl is available, go for the accepted answer - it is simple and memory-efficient (doesn't read the whole input file at once).
Otherwise, consider ghostdog74's Awk answer - it's obscure, but also memory-efficient; a more readable equivalent (POSIX-compliant) is:
awk 'NR > 1 { print prev } { prev=$0 } END { ORS=""; print }' in.txt
END
block, where it is printed without a trailing\n
due to setting the output-record separator (OFS
) to an empty string.If you want a verbose, but fast and robust solution that truly edits in-place (as opposed to creating a temp. file that then replaces the original), consider jrockway's Perl script.
Assuming Unix file type and you only want the last newline this works.
It will not work on multiple newlines...
* Works only if the last line is a blank line.
ruby:
or:
See also Match any character (including newlines) in sed.
Yet another answer FTR (and my favourite!): echo/cat the thing you want to strip and capture the output through backticks. The final newline will be stripped. For example: