Use find and do command on filename without "./" prefix
Performing a cp
on filenames in multiple subdirectories and prefix them with foo-
leads to an error:
$ find my-dir -path "*/*" -execdir sh -c 'cp {} foo-{}' \;
cannot create regular file ‘foo-./blabla.jpg’: No such file or directory
On macOS I don't get this ./
prefix and the command works fine.
Is there a way to cp
the filename without the ./
prefix?
Solution 1:
Even if elsewhere your command works fine, it's still flawed. Never embed {}
in the shell code.
The right approach is:
find my-dir -path "*/*" -execdir sh -c 'cp -- "$1" "foo-${1#./}"' sh {} \;
where ${1#./}
is responsible for removing the leading ./
(if any). Note I used double dash, which is unnecessary (yet harmless) when find
generates names with the ./
prefix, but useful otherwise.
Notes:
- The command doesn't check if the matching
whatever
is a file. You will get a warning fromcp
if it's a directory. - The command doesn't check if
foo-whatever
exists and what it is. If it exists then you will get different results depending on whether it's a file or directory; and depending on if it's processed before or afterwhatever
.