find
returns the path from .
all the way to the file, so each find
result in starts with ./
when you begin your search in the current directory. As a result, your new filename is PRE_./test.txt
, which is test.txt
in a directory called PRE_.
. Since there is no directory called PRE_.
, mv
can't move test.txt
into that directory, so gives you the error message you saw.
If you are only renaming files in the current directory, and not subdirectories, you can just use bash:
shopt -s extglob
for f in !(*.sh) ; do [[ -d "$f" ]] || mv "$f" "PRE_$f" ; done
Thanks to this answer for the !(pattern)
construct in bash, available when extglob
is enabled. It returns all filenames not matching pattern
.
For files in all subdirectories, too, use:
shopt -s extglob globstar
for f in **/!(*.sh) ; do [[ -d "$f" ]] || mv "$f" "${f%/*}/PRE_${f##*/}" ; done
Thanks to this answer for globstar. The %
and ##
chop the path components and stick the PRE_
into the right place, at the beginning of the filename.
Edit The [[ -d "$f" ]] ||
in both of the above prevents the loop from renaming directories.