still this does not work.
it needs to run recursively BUT have the perviously renamed directory name on hand.
if it does not have the "new" name it will not -find- it in the next renaming step.
EDIT: The code has been modified so only the child directory is modified.
Here is a sh script that will surely work:
#!/bin/sh
cat /dev/null > tmp
for f in $(find -type d); do
echo "$f" >> tmp
done
cat /dev/null > tmp2
while read line; do
depth=$(echo "$line" | grep -o "/" | wc -l)
echo "$depth|$line" >> tmp2
done < tmp
sort -nr tmp2 > tmp
while read line; do
folder=$(echo "$line" | cut -d'|' -f2)
parent=${folder%/*}
child=$(echo ${folder##*/} | tr [A-Z] [a-z])
newfolder=$(echo "$parent/$child")
echo mv "$folder" "$newfolder"
done < tmp
exit 0
It's a bit hackish but the trick is to rename deeper directories first
The first block of code creates a tmp file containing what find finds
The second block calculates the depth of the directories and writes to tmp2, for each directory, a line in the form "5|/path/to/the/direc/tory". Then the file is sorted so deeper directory are first in the file tmp
The third block actually rename each child directory with a pattern of choice
Remove the echo on the last line in the third loop to rename the files
but i can not "cd" in the for loop.(the commented line in function stepin)..any ideas?
#!/bin/bash
MYNAME=$0
FROM=$1
TO=$2
function list(){
# lists all directories on the current level
for f in `find ./ -type d`; do echo $f; done | cut -d / -f 1,2 | uniq | tail -n +2
}
function rename(){
# renames all directories on this level
# then calls "stepin" which moves on directorylevel deeper
for l in `list`
do
n=`echo $l | sed "s/${FROM}/${TO}/g"`
if [ "$l" != "$n" ];then
echo "RENAMING: " $l " --> " $n
mv $l $n
echo ""
fi
done
stepin
}
function stepin(){
# lists all directories on the current level to "cd" into them
# from here "one level deeper" rename does his job again
echo "stepping in..."
#for s in `list`; do echo "next dir is: "$s "it contains"; ls -l $s; done
for s in `list`; do echo "next dir is: "$s "it contains"; ls -l $s; cd $s; rename; done
}
echo "OLD"; list; echo "OLD_END"
rename
echo "NEW"; list; echo "NEW_END"
I added a bit of code next to your for s in `list` loop to go back to the parent directory, so ls and cd won't fail.
#At the top of the script
CURRDIR="$PWD"
#your script....
for s in `list`; do echo "next dir is: "$s "it contains"; ls -l $s; cd $s; rename; done;
cd ..
#Do not go back more than the working directory
if [ "$PWD" = "$CURRDIR" ]; then exit 0; fi
thank you so much ...
it took me a night and your help...but now it s working.
but onestly...i realy need you to explain to me what your lines do?
cd ..
moeves on directory backwards so from /home/user to /home
but don't I want to move forward?! at least that is waht the function "stepin" is supposed to do" so e.g. /home/user/ to /home/user/direcorty_in_home
this is twisted..sorry I dont get it....could you PELASE comment so I get out this with having learned something?!
thank you
---------- Post updated at 07:03 AM ---------- Previous update was at 06:52 AM ----------
tested it ...still not working all the way
see the underscores in "level_2, level_3 and level_4" of the first directory?
The key to this puzzle is hinted in the first post.
1) Use the "-depth" parameter to "find" such that the deepest directory is acted on first. However the moment you rename a directory your "find" results list is out of date.
2) So! I would suggest breaking out of the loop each time you rename a directory. Then repeat the full process until you get no hits.
3) It's inefficient but has a greater chance of success.
A more efficent approach is to keep the find "results" list up-to-date as you rename directories (but still working from the deepest level up). Unless there are a huge number of directories IMHO this is not really worth the effort.