Software Engineer's Blog

How to get rid of ^M from a text file on Linux of Unix

How to get rid of ^M from a text file on Linux of Unix

You copy a file over from Windows, run it on Linux, and something breaks — a shell script dies with $'\r': command not found, or Git flags every line as changed even though you only touched one. Run cat -v and there’s the culprit: a ^M hanging off the end of every line.

That ^M is a carriage return. Windows ends lines with CR+LF (\r\n); Linux and Unix use LF (\n) alone. The extra \r is what cat -v prints as ^M. Here’s how to strip it with whichever tool you have on hand, and how to confirm it’s actually gone.

$ cat -v HelloWorld.java

public class HelloWorld^M
{^M
	public static void main(String[] args) {^M
		System.out.println("Hello World!");^M
	}^M
}^M

Using the dos2unix command

If it’s installed, dos2unix is the cleanest option — it converts line endings in place, with nothing to redirect.

$ dos2unix filename

On Ubuntu it’s a one-line install if you don’t have it: sudo apt install dos2unix. For converting more than one file, it’s the simplest option.

Using vi/vim editor

Already editing the file in Vim? Strip the carriage returns without leaving the editor. This searches for ^M at the end of every line and deletes it:

:%s/^M$//g

The catch is entering that ^M — you can’t just type caret then M. Press Ctrl and hold it while typing the escape sequence:

  • Vim on Linux: Ctrl + v then Ctrl + m
  • Gvim on Windows: Ctrl + q then Ctrl + m
  • Or type \015 (the octal code for carriage return) in place of ^M

Using sed (stream editor)

sed needs no install and works well inside scripts. The first form matches a literal ^M (again entered with Ctrl + v, Ctrl + m); the second uses \r, which is far easier to type — GNU sed on Ubuntu accepts it, though it’s a GNU extension, not POSIX, so it may not work on BSD/macOS sed:

$ sed -e "s/^M//g" org_file > new_file
$ sed 's/\r//g' org_file > new_file

Note that sed writes to a new file here rather than editing in place. Use sed -i 's/\r//g' file to overwrite the original once you trust the result.

Using tr

For a quick, one-shot strip in a pipe, tr deletes the carriage-return byte directly:

$ tr -d '\r' < org_file > new_file

It can’t edit in place — it only reads a stream — but it’s the shortest thing to type when you’re already piping data around.

Verify it worked

Don’t assume; check. Running cat -v again should show no more ^M:

$ cat -v new_file

Or ask file what line endings it sees — before the fix it reports the CRLF terminators explicitly:

$ file HelloWorld.java
HelloWorld.java: ASCII text, with CRLF line terminators

After a clean conversion, that , with CRLF line terminators note disappears.

Which one should you use?

  • dos2unix — converting one or more files in place, and you can install it. The least fuss.
  • sed -i 's/\r//g' — inside a script, or on a locked-down box where installing anything is off the table.
  • tr -d '\r' — a quick one-off in a pipe.
  • Vim — you’re already in the file and don’t want to drop back to the shell.