100

When I run a particular SQL script in Unix environments, I'm am seeing a '^M' character at the end of each line of the SQL script as it is echoed to the command-line. I don't know on which OS the SQL script was originally created.

What is causing this and how do I fix it?

Paul Reiners
  • 8,896
  • 30
  • 107
  • 178

16 Answers16

80

It's caused by the DOS/Windows line-ending characters. Like Andy Whitfield said, the Unix command dos2unix will help fix the problem. If you want more information, you can read the man pages for that command.

Thomas Owens
  • 107,741
  • 94
  • 299
  • 427
76

Fix line endings in vi by running the following:

:set fileformat=unix

:w

s g
  • 4,057
  • 6
  • 39
  • 67
Tim Abell
  • 8,954
  • 8
  • 70
  • 99
  • 2
    This is a brilliant answer. Many thanks. (saved installing dos2unix, a tool I'd probably only use once) – Jamsi Feb 04 '14 at 22:29
  • 3
    this doesnt remove the `^M`s for some reason. reference file: `/etc/timidity/fluidr3_gm.cfg`. – phil294 Apr 06 '17 at 01:11
39

The cause is the difference between how a Windows-based based OS and a Unix based OS store the end-of-line markers.

Windows based operating systems, thanks to their DOS heritage, store an end-of-line as a pair of characters - 0x0D0A (carriage return + line feed). Unix-based operating systems just use 0x0A (a line feed). The ^M you're seeing is a visual representation of 0x0D (a carriage return).

dos2unix will help with this. You probably also need to adjust the source of the scripts to be 'Unix-friendly'.

Andriy M
  • 71,352
  • 17
  • 87
  • 142
ColinYounger
  • 6,570
  • 5
  • 28
  • 33
  • I wouldn't say current versions of Windows have any kind of DOS *heritage*. They still have compatibility restraints, though. – Joey Mar 08 '13 at 12:30
  • This is the easy way, is you do an automatic conversion tool. Thank's – Pjl Apr 09 '15 at 13:57
  • But why `^M`? Why the '^'? Why the 'M'? – 1737973 Jul 28 '15 at 04:47
  • Because it's a "control character". "^" is the visual representation of clicking the control key. Underneath its just specific bytes, the ^ is how the editor represents them. – Hejazzman Aug 05 '15 at 22:10
24

The easiest way is to use vi. I know that sounds terrible but its simple and already installed on most UNIX environments. The ^M is a new line from Windows/DOS environment.

from the command prompt: $ vi filename

Then press ":" to get to command mode.

Search and Replace all Globally is :%s/^M//g "Press and hold control then press V then M" which will replace ^M with nothing.

Then to write and quit enter ":wq" Done!

Ionică Bizău
  • 93,552
  • 74
  • 254
  • 426
Bernie Perez
  • 12,073
  • 13
  • 41
  • 54
13

Try using dos2unix to strip off the ^M.

Andy Whitfield
  • 2,295
  • 2
  • 19
  • 22
10

In vi, do a :%s/^M//g

To get the ^M hold the CTRL key, press V then M (Both while holding the control key) and the ^M will appear. This will find all occurrences and replace them with nothing.

Brad Mace
  • 26,280
  • 15
  • 94
  • 141
dogbane
  • 242,394
  • 72
  • 372
  • 395
8

The SQL script was originally created on a Windows OS. The '^M' characters are a result of Windows and Unix having different ideas about what to use for an end-of-line character. You can use perl at the command line to fix this.

perl -pie 's/\r//g' filename.txt
Bill the Lizard
  • 369,957
  • 201
  • 546
  • 842
7

The ^M is typically caused by the Windows operator newlines, and translated onto Unix looks like a ^M. The command dos2unix should remove them nicely

dos2unix [options] [-c convmode] [-o file ...] [-n infile outfile ...]

jW.
  • 8,860
  • 12
  • 44
  • 50
5
C:\tmp\text>dos2unix hello.txt helloUNIX.txt

Sed is even more widely available and can do this kind of thing also if dos2unix is not installed

C:\tmp\text>sed s/\r// hello.txt > helloUNIX.txt  

You could also try tr:

cat hello.txt | tr -d \r > helloUNIX2.txt  

Here are the results:

C:\tmp\text>dumphex hello.txt  
00000000h: 48 61 68 61 0D 0A 68 61 68 61 0D 0A 68 61 68 61 Haha..haha..haha  
00000010h: 0D 0A 0D 0A 68 61 68 61 0D 0A                   ....haha..  

C:\tmp\text>dumphex helloUNIX.txt  
00000000h: 48 61 68 61 0A 68 61 68 61 0A 68 61 68 61 0A 0A Haha.haha.haha..  
00000010h: 68 61 68 61 0A                                  haha.  

C:\tmp\text>dumphex helloUNIX2.txt  
00000000h: 48 61 68 61 0A 68 61 68 61 0A 68 61 68 61 0A 0A Haha.haha.haha..  
00000010h: 68 61 68 61 0A                                  haha.  
Alex Bolotov
  • 8,341
  • 9
  • 49
  • 56
4

To replace ^M characters in vi editor use below

open the text file say t1.txt

vi t1.txt

Enter command mode by pressing shift + :

then press keys as mentioned %s/^M/\r/g

in above ^M is not (shift + 6)M instead it is (ctrl + V)(ctrl + M)
leela
  • 536
  • 4
  • 10
  • Your last line is what I was missing from all the previous answers. I kept getting 'no matches found bc I was doing shift+6, so I did what every hacker would and circumvented my misunderstanding with my own solution: record a macro to do $ to go to end of each line and then press x, just repeat macro for num of lines in file. – darethas Aug 13 '13 at 05:46
3

An alternative to dos2unix command would be using standard utilities like sed.

For example, dos to unix:

sed 's/\r$//' dos.txt > unix.txt

unix to dos:

sed 's/$/\r/' unix.txt > dos.txt
MikroDel
  • 6,389
  • 7
  • 37
  • 69
g4th
  • 925
  • 9
  • 14
1

You can remove ^M from the files directly via sed command, e.g.:

sed -i'.bak' s/\r//g *.*

If you're happy with the changes, remove the .bak files:

rm -v *.bak
kenorb
  • 118,428
  • 63
  • 588
  • 624
1

Convert DOS/Windows (\r\n) line endings to Unix (\n) line endings, with tr:

tr '\r\n' '\n' < dosFile.txt > unixFile.txt

Post about replacing newlines from the Unix command line

Community
  • 1
  • 1
0

In Perl, if you don't want to set the $/ variable and use chomp() you can also do:

$var =~ /\r\n//g;

My two cents

Ariel Monaco
  • 2,481
  • 1
  • 17
  • 18
0

od -a $file is useful to explore those types of question on Linux (similar to dumphex in the above).

Allan Wind
  • 7,923
  • 3
  • 20
  • 30
-1

Another vi command that'll do: :%s/.$// This removes the last character of each line in the file. The drawback to this search and replace command is that it doesn't care what the last character is, so be careful not to call it twice.

Scottie T
  • 10,481
  • 9
  • 43
  • 59