I suspect you did something like for f in /path/to/dir*
instead of /path/to/dir/*
. The former will look for files and directories in /path/to
whose name starts with dir
while the latter will iterate over the contents of the direrctory.
In any case, that wouldn't help you because the tr
command you are using would change everything, including /path/to/dir
to upper case, leaving you with /PATH/TO/DIR
which doesn't exist. The good news is that you can do it in a much simpler way.
If you're using bash, you can use ${var^^}
to make a variable's contents upper case. So you can just do:
for f in /path/to/dir/*; do
## get the file's name
name=$(basename -- "$f")
## make the new name
mv -- "$f" /path/to/dir/"${name^^}"
done
Or, to avoid typing out the directory name twice, you could save it in a variable:
targetPath="/path/to/dir"
for f in "$targetPath"/*; do
## get the file's name
name=$(basename -- "$f")
## make the new name
mv -- "$f" "$targetPath"/"${name^^}"
done
However, this is one of the cases where it is simpler and cleaner to just cd
into the target directory and work there:
targetPath="/path/to/dir"
cd -- "$targetPath" &&
for f in *; do
mv -- "$f" "${f^^}"
done
Or, to avoid ending up in the new directory, run the loop in a subshell:
targetPath="/path/to/dir"
( cd -- "$targetPath" &&
for f in *; do
mv -- "$f" "${f^^}"
done
)
Finally, you can also do all this using perl-rename
(known as rename
on Ubuntu and installable with sudo apt install rename
):
rename -n 's|([^/]+)$|uc($1)|e' /path/to/dir/*
The -n
makes rename
just print out what it would do without doing it. If you're satisfied it works, run it again without the -n
to actually rename the files.
-d, --filename, --nopath, --nofullpath
option that avoids the need to capture the basename explicitly I think? So for examplerename -n --no-path '$_ = uc($_)' /path/to/dir/*
– steeldriver Feb 06 '22 at 17:08rename
s there are, it might be safer to leave it out. – terdon Feb 06 '22 at 17:11rename
deserves a separate answer. – reinierpost Feb 07 '22 at 11:40