Matias Barrios
Matias Barrios

Reputation: 5056

sed not working properly inside find's "exec"

I am working on a one-liner to remove the extensions to a bulk of files in a location.

This is what it looks like, and it should work, but it does not:

find . -type f -name '*.txt' -exec mv {} $( echo {} | sed 's/\.txt//g'  )  \;

The replacement never took place. "mv" is stating:

mv: \`./partaa.txt' and `./partaa.txt' are the same file

I know the problem is within here:

$( echo {} | sed 's/\.txt//g'  )

But if I try something like this, it works perfectly:

echo $( echo "partaa.txt" | sed 's/.txt//g' )

Why is it not working when it is part of "exec"?

Upvotes: 1

Views: 297

Answers (1)

Greg Tarsa
Greg Tarsa

Reputation: 1642

What you are trying to do is not supported. In the man page for find in the PRIMARIES section under -exec, it states:

Utility and arguments are not subject to the further expansion of shell patterns and constructs.

However, you can use find to generate fodder for a sed command that creates a command stream that you can pipe into bash. Then you can troubleshoot by removing the bash from the pipeline:

find . -type f -name '*.txt' | sed 's/.*/mv & &/; s/\.txt$//' | bash -x

The first sed s command creates a mv string with both filenames the same, the second s command removes the .txt from the second one.

The '-x' tells bash to display each command as it executes. You can safely omit it.

Upvotes: 2

Related Questions