115

Suppose I have a file called file:

$ cat file
Hello
Welcome to
Unix

I want to add and Linux at the end of the last line of the file. If I do echo " and Linux" >> file will be added to a new line. But I want last line as Unix and Linux

So, in order to work around this, I want to remove newline character at the end of file. Therefore, how do I remove the newline character at the end of file in order to add text to that line?

1
  • 10
    Don't remove it, just use a text editor. sed '$s/$/ and linux/'
    – 123
    Commented Jan 11, 2016 at 15:01

5 Answers 5

111

If all you want to do is add text to the last line, it's very easy with sed. Replace $ (pattern matching at the end of the line) by the text you want to add, only on lines in the range $ (which means the last line).

sed '$ s/$/ and Linux/' <file >file.new &&
mv file.new file

which on Linux can be shortened to

sed -i '$ s/$/ and Linux/' file

If you want to remove the last byte in a file, Linux (more precisely GNU coreutils) offers the truncate command, which makes this very easy.

truncate -s -1 file

A POSIX way to do it is with dd. First determine the file length, then truncate it to one byte less.

length=$(wc -c <file)
dd if=/dev/null of=file obs="$((length-1))" seek=1

Note that both of these unconditionally truncate the last byte of the file. You may want to check that it's a newline first:

length=$(wc -c <file)
if [ "$length" -ne 0 ] && [ -z "$(tail -c -1 <file)" ]; then
  # The file ends with a newline or null
  dd if=/dev/null of=file obs="$((length-1))" seek=1
fi
2
  • 23
    Much better way to remove a trailing newline is perl -pi -e 'chomp if eof' myfile. Compared to truncate or dd it not gonna leave you with a broken file if myfile had actually no trailing newlines.
    – Hi-Angel
    Commented May 27, 2019 at 13:24
  • 6
    @Hi-Angel May I recommend writing that as an answer? I think that would be a very good answer. Commented Sep 12, 2019 at 13:03
66

You can achieve this with perl as:

perl -pi -e 'chomp if eof' myfile

Compared to truncate or dd this not gonna leave you with a broken file if myfile had actually no trailing newlines.

(the answer is constructed from the comment, and based on this answer)

3
  • Thank-you! This conditional method of removing is trailing newline is perfect.
    – xer0x
    Commented Nov 4, 2019 at 18:56
  • Best answer. Too bad for everyone that you were late to the party.
    – webb
    Commented Dec 12, 2020 at 0:14
  • 1
    best answer! Also to make this easy to use, I just defined a little function like this: function chomp() { perl -p -e 'chomp if eof' }. Now I can strip a new line with a pipe like this: cat /tmp/file | chomp.
    – Chris
    Commented Jun 20, 2021 at 23:27
59

Though, you can remove newline character from all lines by using tr -d '\n':

$ echo -e "Hello"
Hello
$ echo -e "Hello" | tr -d '\n'
Hello$

You can remove the newline character at the end of file using following easy way:

  1. head -c -1 file

From man head:

    -c, --bytes=[-]K
              print the first K bytes of each file; with the leading '-',
              print all but the last K bytes of each file
  1. truncate -s -1 file

from man truncate:

    -s, --size=SIZE
              set or adjust the file size by SIZE
SIZE is an integer and optional unit (example: 10M is 10*1024*1024). Units are K, M, G, T, P, E, Z, Y (powers of 1024) or KB, MB, ... (powers of 1000). SIZE may also be prefixed by one of the following modifying characters: '+' extend by, '-' reduce by, '' at least, '/' round down to multiple of, '%' round up to multiple of.
4
  • is head -c -1 file | tee file safe? Wouldn't tee truncate the file before starting?
    – iruvar
    Commented Jan 11, 2016 at 17:14
  • 1
    @1_CR Indeed. The two sides of the pipe start in parallel, it's a matter of who wins the race. Since tee only has to open the file, whereas head has to read and write its contents, tee will in practice win the race except sometimes for very small files. Commented Jan 11, 2016 at 22:46
  • 7
    This doesn't remove last newline, it remove all newlines. IMO quite a big difference.
    – Hi-Angel
    Commented May 27, 2019 at 13:16
  • 1
    Solution 2 should be the accepted answer. If your file is huge you really do not want to read the full file.
    – Ole Tange
    Commented Dec 17, 2020 at 19:28
5

Here's one way with sed -- on the last ($) line of the file, search and replace anything and everything (.*) with "whatever you matched" followed by " and Linux":

sed '$s/\(.*\)/\1 and Linux/' file

An even simpler solution, courtesy of Isaac, is:

sed '$s/$/ and Linux/' file

This replaces the (symbolic) end-of-line with the given text.

0
2
perl -0pi -e "s/\R\z//g" file

Works for "\r" (MAC), "\r\n" (Windows) and "\n" (Linux). For repeated newlines (any tipe) at end of file you can do:

perl -0pi -e "s/\R*\z//g" file

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .