70

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
  • 9
    Don't remove it, just use a text editor. sed '$s/$/ and linux/' – 123 Jan 11 '16 at 15:01
66

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
3
  • 14
    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 May 27 '19 at 13:24
  • 2
    @Hi-Angel May I recommend writing that as an answer? I think that would be a very good answer. – Simon Forsberg Sep 12 '19 at 13:03
  • @SimonForsberg thanks, done. – Hi-Angel Sep 12 '19 at 14:11
37

Though, you can remove newline character from line by 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
    
  2. 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 most, '>' 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 Jan 11 '16 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. – Gilles 'SO- stop being evil' Jan 11 '16 at 22:46
  • 4
    This doesn't remove last newline, it remove all newlines. IMO quite a big difference. – Hi-Angel May 27 '19 at 13:16
  • Solution 2 should be the accepted answer. If your file is huge you really do not want to read the full file. – Ole Tange Dec 17 '20 at 19:28
31

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)

2
  • Thank-you! This conditional method of removing is trailing newline is perfect. – xer0x Nov 4 '19 at 18:56
  • Best answer. Too bad for everyone that you were late to the party. – webb Dec 12 '20 at 0:14
4

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.

1
  • Isaac, I like that suggestion! It's simpler/ more obvious. I will update the answer with it. Thank you! – Jeff Schaller Oct 5 '19 at 17:53
0
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

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.