Wednesday, June 3, 2009

Recursively Replace Ctrl-M

Ctrl-M's are a plague inflicted upon programmers everywhere. I've mentioned a number of ways to deal with them in the past, and some readers have also contributed helpful advice as well. Today I ran into a situation where I needed to do a huge source diff on two different directory trees. My preprocessor happened to strip out all Ctrl-M leading to a bunch of false positives on files that differed. Some Google'ing around lead me to find this gem, which recursively strips Ctrl-M on all files within a given directory.

for file in $(find /path/to/dir -type f); do
tr -d '\r' <$file >temp.$$ && mv temp.$$ $file

In order to give credit where it's due, a user named blowtorch gave the tip at the following forum.


Brian Masney said...

In vi, you can strip out all \r's with :%s/^V^M//g

Gabe said...

You can do this in place using gnu sed with the -i option.

for file in $(find /path -type f); do
sed -i 's/\r//g' $file; done

Owen Raccuglia said...

You can also get out some decent mileage out of dos2unix -- no temp file needed, either. And the name is catchy. ;)

Ben said...

You could use find to do this, I think with
$ find /path/to/files -name "*.c" -exec dos2unix {} +

See the manpage for find for complete details, but the -exec option here replaces {} with matched filenames and the '+' signifies that dos2unix can take multiple filenames. If it doesn't, replace '+' with '\;', backslash required so the semicolon is not interpreted by the shell.

Ben said...

Oh yeah, and dos2unix is part of the 'tofrodos' package, at least on debian/ubuntu.

Unknown said...

Of course, the "-b" flag to diff may also be of use. It'll ignore all differences in the amount of whitespace, so it'll typically only catch any significant differences (unless you're comparing Python code ;-)).

Anonymous said...

Off topic, but does anyone know how to pass an ex command to vim at startup?



Anonymous said...

To clarify what I'm trying to do, a script of mine needs to launch VIM and the vert diffs command.


Chris said...