37

I have this line inside a file:

ULNET-PA,client_sgcib,broker_keplersecurities
,KEPLER

I try to get rid of that ^M (carriage return) character so I used:

sed 's/^M//g'

However this does remove everything after ^M:

[root@localhost tmp]# vi test
ULNET-PA,client_sgcib,broker_keplersecurities^M,KEPLER

[root@localhost tmp]# sed 's/^M//g' test
ULNET-PA,client_sgcib,broker_keplersecurities

What I want to obtain is:

[root@localhost tmp]# vi test
ULNET-PA,client_sgcib,broker_keplersecurities,KEPLER
James Brown
  • 36,089
  • 7
  • 43
  • 59
SoSed
  • 375
  • 1
  • 3
  • 6

11 Answers11

68

Use tr:

tr -d '^M' < inputfile

(Note that the ^M character can be input using Ctrl+VCtrl+M)


EDIT: As suggested by Glenn Jackman, if you're using bash, you could also say:

tr -d $'\r' < inputfile
Community
  • 1
  • 1
devnull
  • 118,548
  • 33
  • 236
  • 227
  • 3
    +1 for the simplest solution. Also note that you can use octal codes in tr, like `tr -d '\012'` to remove newlines for example. And you can use `od -bc inputfile` to browse what codes mean what and are where in a file. – John Zwinck Oct 16 '13 at 14:50
  • 1
    @twalberg I gues `dos2unix` would remove CR only from the end of line. The example in the question doesn't make it evident whether it's present only at the end of line. – devnull Oct 16 '13 at 15:02
  • @devnull I guess maybe it's not universal, but my `dos2unix` has several different options for controlling conversion mode that may be appropriate (in particular the ones for dealing with Mac files, that seem to like to use `^M` line endings). It may not be a perfect solution for the OPs current question, but it's a good thing to know about, hence the "see also...". – twalberg Oct 16 '13 at 15:06
  • 13
    If you're using bash, you can write `tr -d $'\r'` – glenn jackman Oct 16 '13 at 15:10
  • @twalberg => Yes, dos2unix can be made to do this on Mac, see my [answer](http://stackoverflow.com/questions/19406418/remove-m-characters-from-file-using-sed/31517990#31517990), below. – Big Rich Jul 20 '15 at 13:39
  • @glennjackman May I know what does the dollar sign "$" do there? I did some search, but wasn't able to figure it out. Thanks! – user2008151314 Sep 16 '16 at 18:00
  • that is [bash ANSI-C quoting](https://www.gnu.org/software/bash/manual/bashref.html#ANSI_002dC-Quoting) – glenn jackman Sep 16 '16 at 20:47
24

still the same line:

sed -i 's/^M//g' file

when you type the command, for ^M you type Ctrl+VCtrl+M

actually if you have already opened the file in vim, you can just in vim do:

:%s/^M//g

same, ^M you type Ctrl-V Ctrl-M

Yzmir Ramirez
  • 1,281
  • 7
  • 11
Kent
  • 189,393
  • 32
  • 233
  • 301
12

You can simply use dos2unix which is available in most Unix/Linux systems. However I found the following sed command to be better as it removed ^M where dos2unix couldn't:

sed 's/\r//g' < input.txt >  output.txt

Hope that helps.

Note: ^M is actually carriage return character which is represented in code as \r What dos2unix does is most likely equivalent to:

sed 's/\r\n/\n/g' < input.txt >  output.txt

It doesn't remove \r when it is not immediately followed by \n and replaces both with just \n. This fails with certain types of files like one I just tested with.

7
alias dos2unix="sed -i -e 's/'\"\$(printf '\015')\"'//g' "

Usage:

dos2unix file
ling
  • 9,545
  • 4
  • 52
  • 49
  • how can you use this command in a shell script, without alias? kept getting sed to complain about some syntax....like solution with \015 char vs ^M – bjm88 Apr 16 '15 at 18:19
  • 1
    @bjm88 I found this somewhere: `sed 's,'$'\015'',,'` – glormph Oct 21 '16 at 09:38
3

If Perl is an option:

perl -i -pe 's/\r\n$/\n/g' file

-i makes a .bak version of the input file
\r = carriage return
\n = linefeed
$ = end of line
s/foo/bar/g = globally substitute "foo" with "bar"

Chris Koknat
  • 3,305
  • 2
  • 29
  • 30
2

In awk:

sub(/\r/,"")

If it is in the end of record, sub(/\r/,"",$NF) should suffice. No need to scan the whole record.

James Brown
  • 36,089
  • 7
  • 43
  • 59
2

This is the better way to achieve

tr -d '\015' < inputfile_name > outputfile_name

Later rename the file to original file name.

RavinderSingh13
  • 130,504
  • 14
  • 57
  • 93
Mantu
  • 133
  • 1
  • 5
1

I agree with @twalberg (see accepted answer comments, above), dos2unix on Mac OSX covers this, quoting man dos2unix:

To run in Mac mode use the command-line option "-c mac" or use the commands "mac2unix" or "unix2mac"

I settled on 'mac2unix', which got rid of my less-cmd-visible '^M' entries, introduced by an Apple 'Messages' transfer of a bash script between 2 Yosemite (OSX 10.10) Macs!

I installed 'dos2unix', trivially, on Mac OSX using the popular Homebrew package installer, I highly recommend it and it's companion command, Cask.

Community
  • 1
  • 1
Big Rich
  • 5,864
  • 1
  • 40
  • 64
1

This is clean and simple and it works:

sed -i 's/\r//g' file

where \r of course is the equivalent for ^M.

Krishna Vyas
  • 1,009
  • 8
  • 25
MAX TAM
  • 19
  • 1
  • Not all `sed` variants recognize the escape `\r`. In original Unix, it would simply mean a regular `r` character with an unnecessary escape which is simply ignored. This is still the behavior on BSD / macOS. – tripleee Oct 06 '20 at 10:37
0

Simply run the following command:

sed -i -e 's/\r$//' input.file

I verified this as valid in Mac OSX Monterey.

Sujay Kumar
  • 520
  • 8
  • 19
0

remove any \r :

nawk 'NF+=OFS=_' FS='\r'
gawk   3  ORS=   RS='\r' 

remove end of line \r :

mawk2 8 RS='\r?\n'
mawk -F'\r$' NF=1 
RARE Kpop Manifesto
  • 2,453
  • 3
  • 11