I am attempting to rename all directories and files to uppercase with a shell script. What I have works, but not for sub directories. As the directory names are changing during the scripts execution I get things like mv: cannot stat './def/two/three': No such file or directory
I have tried using -depth
with find so it would rename from the bottom up. But still run into the same problem. I though about using cut
to break apart the path on /
and rename that way, but am at a loss.
Here's what I have:
for i in `find . -name "*[a-z]*"`
do new_name=`echo $i | tr '[a-z]' '[A-Z]'`
mv $i $new_name
done
I would appreciate any direction as I feel like this should be a common task, but failed to find a working solution from some Google searches.
Please note, I can not use rename
as it not supported by my distro.
Try this way :
find . -depth |while read LONG; do SHORT=$( basename "$LONG" | tr '[:lower:]' '[:upper:]' ); DIR=$( dirname "$LONG" ); if [ "${LONG}" != "${DIR}/${SHORT}" ]; then mv "${LONG}" "${DIR}/${SHORT}" ; fi; done
or, if you want the readable version (no one-liner) :
find . -depth | \
while read LONG; do
SHORT=$( basename "$LONG" | tr '[:lower:]' '[:upper:]' )
DIR=$( dirname "$LONG" )
if [ "${LONG}" != "${DIR}/${SHORT}" ]; then
mv "${LONG}" "${DIR}/${SHORT}"
fi
done
This will rename files before, then the directory they're in, in the proper order.
lets say you have this directory structure
/somewhere/somethimg/
/somewhere/somethimg/dir1
/somewhere/somethimg/dir1/dir2
I think you should start the rename with dir2 then go to dir1 and so on
This script should rename all files/directories in current path in "leaf" first order to make things work.
#!/bin/bash
IFS=$'\n';
TMP=/tmp/file_list
rm -f ${TMP};
for file in `find .`
do
num=`echo $file | grep -o "/" | wc -l`;
echo "$num $file" >> ${TMP};
done
sort -n -r ${TMP} | cut -f 2 -d ' ' > ${TEMP}.temp;
for file in `cat ${TEMP}.temp`
do
echo $file;
## Code to rename file here. All subdirectories would already have been renamed
done