How to Use Find - exec and Tr to process a large number of files

bash, exec, find, tr

Solution

If you want to redirect the output of a command used with `-exec`, you need to execute a shell command. Moreover you'd need to redirect the output to a new file and move it back to the original filename.

Say:

find . -type f -exec sh -c 'tr -d "\r" < "{}" > "{}".new && mv "{}".new "{}"' -- {} \;

An alternate would be to use `sed`:

find . -type f -exec sed -i 's/\r//' {} \;

or `dos2unix` (as pointed out by kojiro):

find . -type f -exec dos2unix {} \;

Problem

I'm having a little trouble with find and exec in bash: Suppose I have a bunch of files that I need to replace '\r' characters in. (previous question: Joining Columns on Command Line with Paste or PR Not Working) For each file, I want to read it, and replace all the '\r', and then write it back to the same file name: The command I'm using is `find . -exec cat {} | tr -d "\r" > {} \;`, but I'm getting two errors: ``` tr: extra operand `;' Only one string may be given when deleting without squeezing repeats. Try `tr --help' for more information. find: missing argument to `-exec' ``` it seems like `tr` is interpreting ';' to be an argument, while `-exec` is not recognizing it. Is there a way to change this? I'm also creating {} as a file in the directory, instead of having {} being substituted for the file name. I've also tried: ``` find . -exec cat {} | tr -d "\r" > "new_{}"; \; ``` but `"new_{}"` does not turn into `"new_filename"`, bash just takes it literally and creates a file called `"new{}"`. Thanks!

Original source