This is a case where you should stuff the code execution into a spawned shell.
find . -name '*~' -exec sh -c 'cp "$0" "${0%~}"' {} \;
This way you don't need to write a script. You just do it in a one-liner.
Note: You don't need the --
"end of options" specifier for cp
here, because find
will prefix the files found with ./
, which will prevent them from being parsed as options to cp
.
(The exception to this ./
prefix is if the current directory .
is itself "found," but of course that name doesn't end with a tilde, nor could it be mistaken as an option flag.)
I would even use a spawned shell for appending a tilde to the copy's name; in other words I'd use:
find . -name string -exec sh -c 'cp "$1" "$1"~' find-sh {} \;
in preference to:
find . -name string -exec cp {} {}~ \; # Don't use this!
as the latter is unspecified by POSIX and therefore unportable.
From the POSIX specifications for find
:
If a utility_name or argument string contains the two characters "{}", but not just the two characters "{}", it is implementation-defined whether find replaces those two characters or uses the string without change.
... If more than one argument containing the two characters "{}" is present, the behavior is unspecified.
--
as an options terminator is guideline 10. Fixed answer. – Wildcard Nov 07 '16 at 23:51