Rename files and directories with find -execdir | rename
If you are going to rename both files and directories not simply with a suffix, then this is a good pattern:
PATH="$(echo "$PATH" | sed -E 's/(^|:)[^\/][^:]*//g')" \
find . -depth -execdir rename 's/findme/replaceme/' '{}' \;
The awesome -execdir
option does a cd
into the directory before executing the rename
command, unlike -exec
.
-depth
ensure that the renaming happens first on children, and then on parents, to prevent potential problems with missing parent directories.
-execdir
is required because rename does not play well with non-basename input paths, e.g. the following fails:
rename 's/findme/replaceme/g' acc/acc
The PATH
hacking is required because -execdir
has one very annoying drawback: find
is extremely opinionated and refuses to do anything with -execdir
if you have any relative paths in your PATH
environment variable, e.g. ./node_modules/.bin
, failing with:
find: The relative path ‘./node_modules/.bin’ is included in the PATH environment variable, which is insecure in combination with the -execdir action of find. Please remove that entry from $PATH
See also: https://askubuntu.com/questions/621132/why-using-the-execdir-action-is-insecure-for-directory-which-is-in-the-path/1109378#1109378
-execdir
is a GNU find extension to POSIX. rename
is Perl based and comes from the rename
package. Tested in Ubuntu 18.10.
Rename lookahead workaround
If your input paths don't come from find
, or if you've had enough of the relative path annoyance, we can use some Perl lookahead to safely rename directories as in:
git ls-files | sort -r | xargs rename 's/findme(?!.*\/)\/?$/replaceme/g' '{}'
I haven't found a convenient analogue for -execdir
with xargs
: Xargs: change working directory to file path before executing?
The sort -r
is required to ensure that files come after their respective directories, since longer paths come after shorter ones with the same prefix.
1Do you have Debian
rename
or Red Hatrename
? – Ignacio Vazquez-Abrams – 2010-11-20T16:42:51.953@Ignacio: Ubuntu = Debian? – endolith – 2010-11-20T16:44:19.740
Yes, Ubuntu is a Debian derivative. – Ignacio Vazquez-Abrams – 2010-11-20T20:39:36.257