108

We have 10 PC with some version of Ubuntu and only remote access. While doing some upgrades to custom software I did not notice that the line endings in some scripts were Windows version (CR+LF) and not the Unix version (LF). So now when I want to launch the script it gives an error:

bash: /usr/local/bin/portsee: /usr/bin/python^M: bad interpreter: No such file or directory

Is there a way to change all line endings in a script from terminal. The thing is that I can not install any new software to this group of PC-s.

NonStandardModel
  • 3,350
  • 7
  • 27
  • 45

2 Answers2

181

Option 1: dos2unix

You can use the program dos2unix, which is specifically designed for this:

dos2unix file.txt

will replace all CR from all lines, in place operation.

To save the output in a different file:

dos2unix -n file.txt output.txt

You might need to install it first by:

sudo apt-get install dos2unix

Option 2: sed

Or you can use sed to replace all CR (\r) from line endings:

sed -i.bak 's/\r$//' file.txt

With option -i, the file will be edited in-place, and the original file will be backed up as file.txt.bak.

wjandrea
  • 14,109
  • 4
  • 48
  • 98
heemayl
  • 90,425
  • 20
  • 200
  • 267
  • 3
    `dos2unix` and `unix2dos` are present in cygwin as well – Pallav Jha Jul 23 '19 at 09:00
  • 2
    [This answer](https://unix.stackexchange.com/a/279818/267627) shows applying `dos2unix` recursively. Useful when moving a git repo from windows to ubuntu. – Nagabhushan S N Aug 03 '20 at 08:11
  • 3
    `sed` worked for me but had to supply the global flag as in: ```sed -i.bak 's/\r$//g' file.txt``` – Jono Nov 02 '20 at 17:58
  • If anyone else gets an `illegal byte sequence` error when using the `sed` command, just add this one the same line before the sed command: `LC_ALL=C sed ...` – Nate Nov 08 '21 at 22:12
  • You can do the same thing with perl where you can update multiple files at once: `perl -pi.bak -e 's/\r$//' manyFiles.* ` For each file, there will be a .bak file with the original contents. – Charles Plager Jul 16 '23 at 17:03
6

The sed solution is not portable to all platforms. It didn't work for me on macOS unless I did brew install gsed and used gsed 's/\r$//'.

For a solution that works in most places without installing anything, I use

tr -d '\r'

To edit a file in-place, I produce the new data in a subshell before erasing and overwriting the original file:

echo "$(tr -d '\r' < file)" > file
MusashiAharon
  • 163
  • 1
  • 4
  • [Sponge from moreutils](https://manpages.debian.org/testing/moreutils/sponge.1.en.html) is a nice utility for reading and writing in the same line as well: `tr -d '\r' – David Oct 27 '21 at 12:02
  • Useful if you have `sponge` installed, but it's not installed by default on macOS. – MusashiAharon May 13 '22 at 20:12