Firstly, it’s good to remember these following points:

  • CR is for Carriage Return
  • LF is for Line Feed
  • On windows line endings are represented by CRLF (CR+LF)
  • On Linux line endings are represented by LF
  • In a shell script you represent CR by \r and LF by \n

(Some history: historically linefeed (LF) was used to advance the paper by one line on printers and hardcopy terminals (teleprinters); carriage return (CR) returned the print head to the start of the line).

Then if you try this (-e option in order \r is interpreted):

$> echo -e "hello\rgoodbye"

hello is written and then \r makes a return to the line beginning without a line break, goodbye is written on top of hello.

If a file contains only CRLF then Linux vim editor hides them, and displays [dos] next to the file name as illustrated here:

but if you add a line ending with LF, then vim will decide to interpret the file as a file with LF line endings:

echo "it's a new Linux line added" >> file_edited_on_windows.txt

Then vim display ^M instead for CR as illustrated here:

To remove these characters, we have to remove all CR in order to have a file with only LF as line ending.

sed -i 's/\r$//' targetfile 	# DOS to Unix

The inverse is possible:

sed -i 's/$/\r/' targetfile	# Unix to DOS