6

When using

$ find . -name string~ -exec cp {} FOO \;

is there a way to use {} in FOO to remove the tilde character as we usually do with bash substrings

e.g. :

 $ echo ${string%substring}

I aim to copy the files named string~ to string (the opposite of $ find . -name string -exec cp {} {}~ \;).

7

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.

  • @StéphaneChazelas, aha, yes, I see—treatment of -- as an options terminator is guideline 10. Fixed answer. – Wildcard Nov 7 '16 at 23:51

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.