To remove all newlines you could, say:
tr -d '\n' < days.txt
cat days.txt | tr -d '\n'
but how would you use tr
to remove just the newline at the end/bottom of a text file?
I'm not sure to specify just the last one.
To remove all newlines you could, say:
tr -d '\n' < days.txt
cat days.txt | tr -d '\n'
but how would you use tr
to remove just the newline at the end/bottom of a text file?
I'm not sure to specify just the last one.
A simpler solution than the accepted one:
truncate -s -1 <<file>>
From the truncate
man page (man truncate
):
-s, --size=SIZE
set or adjust the file size by SIZE
SIZE may also be prefixed by one of the following modifying characters:
'+' extend by, '-' reduce by, '<' at most, '>' at least, '/' round down
to multiple of, '%' round up to multiple of.
Take advantage of the fact that a) the newline character is at the end of the file and b) the character is 1 byte large: use the truncate
command to shrink the file by one byte:
# a file with the word "test" in it, with a newline at the end (5 characters total)
$ cat foo
test
# a hex dump of foo shows the '\n' at the end (0a)
$ xxd -p foo
746573740a
# and `stat` tells us the size of the file: 5 bytes (one for each character)
$ stat -c '%s' foo
5
# so we can use `truncate` to set the file size to 4 bytes instead
$ truncate -s 4 foo
# which will remove the newline at the end
$ xxd -p foo
74657374
$ cat foo
test$
You can also roll the sizing and math into a one line command:
truncate -s $(($(stat -c '%s' foo)-1)) foo
If you are sure the last character is a new-line, it is very simple:
head -c -1 days.txt
head -c -N
means everything except for the last N bytes
If you want to modify the file in-place:
truncate -s -1 days.txt
It will remove the last byte of the file, regardless of what it is.
I think your best bet is Perl:
perl -0pe 's/\n\Z//' days.txt
The -0
causes perl to treat the whole file as one big string. The -p
tells it to print that string back out after running the program on it. And the -e
says "here's the program to run".
The regular expression \n\Z
matches a newline, but only if it's the last character in a string. And s/\n\Z//
says to replace such a newline with nothing at all, deleting it.
The above command outputs the new version of the file, but you can instead modify the existing one by adding the -i
("in-place") option, optionally with a suffix that will be used to name a backup copy of the file before modifying it:
perl -i.bak -0pe 's/\n\Z//' days.txt
This solution is safe in that if the last character is not a newline, it won't be touched. The other solutions which simply remove the last byte no matter what may corrupt such a file.
Try this command:
sed '$ { /^$/ d}' days.txt
You can read it as: "check if last line is an empty line. if so delete this line". I tested with both cases: first with a file having a new line at the end and an other time with a file ending with something else.
Another Sed solution:
sed -z s/.$// days.txt
With the -z
option, it interprets the file as a single long line (newlines are embedded as \n
), then s
matches the single character .
before the end of line (= end of file) $
, and changes it into nothing. No need for quoting the command.
If you are not sure the last character is a newline, then you do either of these:
sed -z s/\\n$// days.txt
sed -z 's/\n$//' days.txt
If you want to remove the newline at the end of the file, you can use:
truncate -s -1 file_name.txt
The change will be saved in the file.