user2682459
user2682459

Reputation: 1029

BASH find and replace in all files in directory using FIND and SED

I need to look for and replace certain strings for all files in a directory, including sub-directories. I think I'm nearly there using the following method which illustrates my general approach. I do much more inside the -exec than just this replace, but have removed this for clarity.

#!/bin/bash
#call with params: in_directory out_directory

in_directory=$1
out_directory=$2
export in_directory
export out_directory

#Duplicate the in_directory folder structure in out_directory
cd "$in_directory" &&
find . -type d -exec mkdir -p -- "$out_directory"/{} \;

find $in_directory -type f -name '*' -exec sh -c '
    for file do  
        #Quite a lot of other stuff, including some fiddling with $file to 
        #get rel_file, the part of the path to a file from 
        #in_directory. E.g if in_directory is ./ then file ./ABC/123.txt
        #will have rel_file ABC/123.txt

        cat $file|tr -d '|' |sed -e 's/,/|/g' > $out_directory/$rel_file
    done
' sh {} +

One issue is likely how I've tried to write the file to pipe the output to. However, this isn't the main/only issue as when I replace it with an explicit test path I still get the error |sed -e 's/,/|/g' |No such file or directory which makes me think the cat $file part is the problem?

Any help is massively appreciated as always - this is only the second BASH script I've ever had to write so I expect I've made a fairly basic mistake!

Upvotes: 2

Views: 378

Answers (1)

Etan Reisner
Etan Reisner

Reputation: 80921

Your "inner" single quotes are being seen as "outer" single quotes and causing you problems. You think you are quoting the | in the tr command but what you are actually doing is ending the initial single-quoted string having an unquoted | and then starting a new single-quoted string. That second single-quoted string then ends at the single-quote that you believe is starting the sed script but is instead ending the previous single-quoted string, etc.

Use double quotes for those embedded single quotes if you can. Where you can't do that you have to use the '\'' sequence to get a literal single-quote in the single-quoted string.

Upvotes: 3

Related Questions