I have the following type of folder structure containing thousands of folders.

The folder names are as such with different names etc



What I need to achieve is the following: I want the folders to be renamed e.g. from .test to test, and then move .test.subfolder so that the folder .subfolder is within the folder test without the ., and then .test.subfolder.subsubfolder so that subfolder is within the folder test and subsubfolder is within test/subfolder.

This needs to be recursive since there are many folders. Keep in mind that the files within the folders should still need to be intact.

Is this at all possible?


This bash script does what you need:

for dir in .*/ ; do
    [[ $dir == ./ || $dir == ../ ]] && continue  # Skip the special dirs
    new=${dir#.}                                 # Remove the dot at the beginning
    new=./${new//.//}                            # Replace dots with slashes, prepend ./
    new=${new%/}                                 # Remove the trainling slash
    mkdir -p ${new%/*}                           # Create the parent dir
    mv "$dir" "$new"                             # Move the dir to destination

Yes it is quite possible. What you need to do is that you need to read all the file names in your path and account for spaces,dots e.t.c. If you want to do that efficiently, you can use this thread : How do I perform an action on all files with a specific extension in subfolders in an elegant way?

Now once you have read the files in the path name you have to lay down a rule.

For example let us consider this structure :


What you have got to do is that you have to count the occurrence of the word sub in each of the file names. So if the count is : 0 , it is the parent folder, if count : 1, it is a 1st level child, if count : 3--> it's a 2nd level child and so on and so forth(level is deduced form the structure provided by you)

Hence a possible pseudo code will look like :

  if(filename contains(".test"))
   if(count ==0)
   else if(count ==1)
   1stLevelChild();//and so on

Now according to the result that you are getting here, you just have to use the move command to move the files in appropriate folders.


This is pretty easy in zsh, thanks to zmv. Since the wildcard .* expands file names in lexicographic order, a to-be-parent directory will always be renamed before its children, so e.g. test will already exist by the time .test.subfolder is renamed.

zmv '.(*)' "${1//./\/}"

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.