Super User is a question and answer site for computer enthusiasts and power users. Join them; it only takes a minute:

Sign up
Here's how it works:
  1. Anybody can ask a question
  2. Anybody can answer
  3. The best answers are voted up and rise to the top

I use Linux. There is a pesky ^M (Windows cariage return) somewhere hidden in thousands of configuration files, and I have to find it, because it makes the server fail.

How do I find ^M among a directories hierarchy full of configuration files?

I think I can not enter ^M on the bash command line. But I have it in a text file that I called m.txt

share|improve this question
    
Related: Remove carriage return in Unix. – 40XUserNotFound May 15 '14 at 21:17
    
windows would be ^M^J – barlop Sep 20 '15 at 1:43
up vote 53 down vote accepted
grep -r $'\r' *

Use -r for recursive search and $'' for c-style escape in Bash.

More, if you are sure it's text file, then it should be safe to run

tr -d $'\r' < filename

to remove all \r in a file.

If use GNU sed, -i can perform in-place edit, so you won't need to write back:

sed $'s/\r//' -i filename
share|improve this answer
7  
@Nicolas: You can enter a ^M at the command line by pressing ^V^M, but it's better to use $'\r'. – Dennis Williamson Oct 1 '10 at 5:54
    
Great, it works! Thanks for the ^V^M trick too :-) – Nicolas Raoul Oct 1 '10 at 5:56
4  
Under Cygwin, -U is needed to make this work. And -n will tell you the line number: grep -r -U -n -e $'\r' – Rainer Blome Jan 3 '13 at 16:16
2  
Add an -l to the grep command to just view the filenames. Else you might be bombarded with matching lines. – Brendan Byrd Mar 25 '14 at 20:28
1  
@uprego not sure if you understand them now, but fyi and other's, search $' read the first hit in manpage bash(1), basically, you can see it as if you were writing C literal string. As for the command < filename, the use of < or > is called redirection, this is first time I have seen anyone called it greater expression. Search REDIRECTION in bash(1). – livibetter Sep 23 '15 at 2:03

When I tried, I could tell it was sort-of working, but the lines were printing blank. Add in the option:

--color=never

If you get this issue, I think it's the escape characters for color highlighting interfering with the \r character.

share|improve this answer

If your server does not have a bash shell, an alternative is to use the -f option on grep, in combination with a prepared file containing \r.

To create the file:

$ echo -ne '\r' > /tmp/cr                    --or--                   $ printf '\r' > /tmp/cr

$ od -c /tmp/cr
0000000  \r
0000001

To actually do the search

$ grep -f /tmp/cr *.html *.php *.asp *.whatever

or you can be a little lazy and just type *,

$ grep -f /tmp/cr *

The -f filename option on grep is used to specify a file that contains patterns to match, one per line. In this case there's only one pattern.

share|improve this answer

If you are on a Mac and use homebrew, you can do:

brew install tofrodos
fromdos file.txt

to remove all the Windows carriage returns from file.txt

To switch back to Windows carriage returns,

todos file.txt
share|improve this answer
    
to search in a folder and clean all files coming from dos, run this command : find . -type f -name "*.java" | xargs fromdos – Taiko May 19 '14 at 3:38

In regular expression style, various newlines:

Windows (CR LF)
\r\n

Unix (LF)
\n

Since the \r\n sequence is fairly unique, I think you should be able to search for it that way?

To make things worse Macs used to have just '\r' in place of newline. I cannot verify this, but I don't think MacOSX generations does that any more.

Older Macs (CR)
\r

share|improve this answer
    
In the directory that contains m.txt, grep "\r\n" * gives no result. No result either for egrep -e "\r\n" * nor grep -E "\r\n" * – Nicolas Raoul Oct 1 '10 at 5:54
    
@nicolas ah, I misunderstood.. you meant CR only \r my bad. A full windows newline is indeed \r\n or CRLF – Jeff Atwood Oct 1 '10 at 5:58

Following up on previous answers, the 'tr' method is good:

533$ if [[ -n "tr -cd "\r" <~/.bashrc" ]]; then echo "DOS"; else echo "UNIX"; fi

UNIX

534$ if [[ -n "tr -cd "\r" <dosfile.txt" ]]; then echo "DOS"; else echo "UNIX"; fi

DOS

share|improve this answer

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .