Mitya
Mitya

Reputation: 11

Unexpected behavior of find -exec

I found an unexpected to me behavior of "find -exec" bash command and I would appreciate some interpretation. The same job can be done with "for file_name in find ....; do...." loop, so the question is why it doesn't work with -exec option of find.

There are two folders (SRC/ and src/) with the same set of files. I want to compare the files in these folders:

find src/ -type f -exec sh -c "diff {} `echo {} | sed 's/src/SRC/'`" \;

this, however, doesn't compare the files... Due to some reason sed command doesn't make the the substitution. If there is only one file, e.g., "a", in each of this folders then a command

find src/ -type f -exec sh -c "echo {} `echo {} | sed 's/src/SRC/'`" \;

outputs

src/a src/a

if one does a similar thing in bash, all the following commands give the same result (SRC/a):

echo src/a | sed 's/src/SRC/'
echo `echo src/a | sed 's/src/SRC/'`
sh -c "echo src/a | sed 's/src/SRC/'"
sh -c "echo `echo src/a | sed 's/src/SRC/'`"

but if this commands are supplied to "find -exec ..." the outputs are different:

find src/ -type f -exec bash -c "echo {} | sed 's/src/SRC/'" \;

gives "SRC/a"

and

find src/ -type f -exec bash -c "echo `echo {} | sed 's/src/SRC/'`" \;

gives "src/a"

Is that the expected behavior?

Upvotes: 1

Views: 139

Answers (1)

Andreas Louv
Andreas Louv

Reputation: 47099

Use single quotes for sh -c for the script is interpreted by your shell first. And Pass the filename as an argument for sh instead of using {} inside the quotes:

find src/ -type f -exec sh -c 'diff "$1" "$(printf "%s\n" "$1" | sed "s/src/SRC/")"' _ {} \;

Or with bash:

find src/ -type f -exec bash -c 'diff "$1" "${1/src/SRC}"' _ {} \; 

Upvotes: 1

Related Questions