LinuxQuestions.org

LinuxQuestions.org (/questions/)
-   Linux - Newbie (https://www.linuxquestions.org/questions/linux-newbie-8/)
-   -   Rename subdirectories recurseively (https://www.linuxquestions.org/questions/linux-newbie-8/rename-subdirectories-recurseively-4175557582/)

SuzDouk 10-30-2015 12:55 PM

Rename subdirectories recurseively
 
I have mulitple folder names in a hierarchy that need to be changed. For instance, "Sandbox" is the first directory in my root. It has hundreds of folders in it, and those folders have several folders within them that are consistently named. For example;
C:
/Sandbox/Folder One/Next Folder/Next Next Folder
/Sandbox/Folder Two/Next Folder/Next Next Folder
/Sandbox/Folder Three/Next Folder/Next Next Folder

I would like to be able to change all folders named "Next Next Folder" to, say, "Folder Level 2" recursively. In my newbieness, I have tried the following command (without sucess, I might add):

find . -name 'INVESTIGATOR FINANCIAL CERTIFICATIONS' -type f -exec bash -c 'mv "$1" "${1/\/'INVESTIGATOR FINANCIAL CERTIFICATIONS_/InvFinancCert/}"' -- {} \;

Is it even possible to change subdirectory names within subdirectories without cd'ing down the whole filepath? I cannot find anything on this question on the "internets."

Thank you, in advance, for your help.

suicidaleggroll 10-30-2015 01:22 PM

Quote:

Originally Posted by SuzDouk (Post 5442461)
Is it even possible to change subdirectory names within subdirectories without cd'ing down the whole filepath? I cannot find anything on this question on the "internets."

Sure, you just need to use dirname and basename to split the directory from its parents, so you can rename it and then put it back in the same directory structure, eg:

Code:

for i in Sandbox/*/*/Next\ Next\ Folder; do
  thisparent=$(dirname "$i")
  thischild=$(basename "$i")

  newchild=${thischild/Next Next Folder/Folder Level 2}
  mv "$i" "$thisparent/$newchild"
done

I would be cautious doing it recursively in one command with a find, because the find runs once and then then loop is executed on the result. As soon as you rename one directory the names of all of the children will be different, and subsequent iterations of the loop will fail because the names returned from find will no longer be valid. I would do it one level at a time, which is easy with globbing patterns.

SuzDouk 11-02-2015 10:07 AM

Firstly, thank you for taking the time to help me with this command.

Secondandly, when I run this command (substituting "Next Next Folder" with "INVESTIGATOR FINANCIAL CERTIFICATIONS" the true name of the folder, I get the error - mv: cannot stat Sandbox/*/*/INVESTIGATOR FINANCIAL CERTIFICATIONS: No such file or directory.

Substituting your example with my actual filename, these are the commands I ran:

for i in Sandbox/*/*/INVESTIGATOR\ FINANCIAL\ CERTIFICATIONS; do
thisparent=$(dirname "$i")
thischild=$(basename "$i")

newchild=${thischild/INVESTIGATOR FINANCIAL CERTIFICATIONS/InvFincCert}
mv "$i" "$thisparent/$newchild"
done

Soooo, what am I doing wrong?

suicidaleggroll 11-02-2015 10:19 AM

Do you have directories called "INVESTIGATOR FINANCIAL CERTIFICATIONS" on the third layer down from Sandbox?

Eg: "Sandbox/something/somethingelse/INVESTIGATOR FINANCIAL CERTIFICATIONS"

grail 11-02-2015 11:37 AM

I noticed the 'C:' at the start of the post, are these folders/files on a Windows machine?

SuzDouk 11-03-2015 03:05 PM

Q1: No. My apoligies, the correct folderpath is C:Sandbox/Folder level 2/INVESTIGATOR FINANCIAL CERTIFICATIONS. I did, however, take out one level in the command, e.g. for i in Sandbox/*/INVESTIGATOR FINANCIAL CERTIFICATIONS; do, but I recived the same error.
Q2: Yes. The files and folders are on a Windows machine. I have Cygwin installed to run commands. Is it a DOS vs Unix issue?

suicidaleggroll 11-03-2015 04:03 PM

You can't run the script I posted in DOS/Powershell, it needs to be in BASH. Cygwin would work, but then you need to modify your path, since C:\ is /cygdrive/c in cygwin. So C:\Sandbox\ becomes /cygdrive/c/Sandbox/.

chrism01 11-03-2015 05:39 PM

Its also going to simplify your life in the long run if you can avoid using spaces in file/dir names.
They can be handled by using extra quoting everywhere you reference them but its a PITA and makes code messy/fragile/hard to read.
Consider using underscores.

The underlying problem is that the *nix convention is that spaces are used to separate param values fed to a program/tool.
Just something to be aware of.
HTH

SuzDouk 11-17-2015 10:59 AM

suicidaleggroll: I am using BASH through the Cygwin command-line interface for Windows.
I launch Cygwin, change directory to c:/Sandbox, then followed your example. I am sure it is user error but, being the user, I can't see the error of my ways.

chrism01: I agree with your suggestion. Unfortunately, I work in a customer's environment wherein they have created folders with spaces, and a whole lot of other problematic data.
Thank you for taking the time to educate me on the *nix convention.

Suzanne

suicidaleggroll 11-17-2015 11:07 AM

If you're already inside the Sandbox directory, then you can't access "Sandbox/*/INVESTIGATOR...", it would simply be "*/INVESTIGATOR...". Unless your path is actually C:\Sandbox\Sandbox\*\INVESTIGATOR...

Forget the loop and the script, and just use ls. "ls -d */INVESTIGATOR..." or "ls -d Sandbox/*/*/INVESTIGATOR..." or whatever it takes to actually list the files/directories you want to rename, and then use that in the script.


All times are GMT -5. The time now is 09:02 AM.