folder rename on mass

jimleslie1977

New Member
Credits
72
could somebody help me with a bash script to run on a linux server to rename several hundred folders. An example would be to rename "folder1" to "folder1_deleteme"

Thanks
 


JasKinasis

Well-Known Member
Credits
1,193
Yes, there are a number of us here who can help. But we'll need a little more information first.

Like - How should the script identify the directories to rename?
Or are you just going to feed it a list of paths?

Also where are the directories on your system? Are they in different locations? Or all in a fixed location?

The more information you can give us, the more help we can provide.
 

captain-sensible

Well-Known Member
Credits
3,597
if i have a directory called "play" on my Desktop and inside I have dirs one, two, three and script called dirName inside play. Then :

cd Desktop/play
chmod +x dirName

./dirName

will change all directories to :

bash-5.0$ tree -L 1
.
├── dirName_bk
├── one_bk
├── three_bk
└── two_bk

3 directories, 1 file
bash-5.0$ //but also chnages bash script name- use as a starting point?


bash script:



#!/bin/bash
for d in *;
do mv "$d" "${d%.*}_bk";

done
 

jimleslie1977

New Member
Credits
72
thanks in advance for the help.

I have a list of folder names to be renamed (about 8000)

they are all subfolders in the same root folder, but are not necissarily at the same folder level, for example /nas/quota/slot_3/home/folders to be renamed> or /nas/quota/slot_3/slot_2/home/folders to be renamed>

Thanks
if i have a directory called "play" on my Desktop and inside I have dirs one, two, three and script called dirName inside play. Then :

cd Desktop/play
chmod +x dirName

./dirName

will change all directories to :

bash-5.0$ tree -L 1
.
├── dirName_bk
├── one_bk
├── three_bk
└── two_bk

3 directories, 1 file
bash-5.0$ //but also chnages bash script name- use as a starting point?


bash script:



#!/bin/bash
for d in *;
do mv "$d" "${d%.*}_bk";

done
I guess this would work ok if all folders where in the same folder, inmy case they may be in different subfolders from the same root ?
 

JasKinasis

Well-Known Member
Credits
1,193
if i have a directory called "play" on my Desktop and inside I have dirs one, two, three and script called dirName inside play. Then :

cd Desktop/play
chmod +x dirName

./dirName

will change all directories to :

bash-5.0$ tree -L 1
.
├── dirName_bk
├── one_bk
├── three_bk
└── two_bk

3 directories, 1 file
bash-5.0$ //but also chnages bash script name- use as a starting point?


bash script:



#!/bin/bash
for d in *;
do mv "$d" "${d%.*}_bk";

done
I hate to break it to you @captain-sensible , but that snippet will rename everything in the current directory. Appending _bk to files, directories, sym-links etc etc!

for d in *; sets up a for loop and creates a variable d which will be populated with * (glob for everything) in the current working directory.

Each time through the for loop, the variable d will be populated with the name of a file-system object in the current directory.
The mv command then renames the object to append _mv to the end of it.

So the mv command will effectively rename EVERYTHING in the directory. Not just directories.

Also, if the object is a file with an extension - the file-extension is completely replaced with _bk. So for example file1.txt would become file1_bk.

So for this example, you'd probably be better off putting in a check that the target is a directory. Like this:
Bash:
#!/usr/bin/env bash
for d in * ; do
  if [[ -d "$d" ]] ; then
    mv "$d" "$d"_bk
  fi
done
That way only the directories will be renamed and the files will be left intact.
The files in this directory might be wanted! It may only be the directories that should be removed. So renaming them and losing their original file-extensions could potentially be a bad thing!


thanks in advance for the help.

I have a list of folder names to be renamed (about 8000)

they are all subfolders in the same root folder, but are not necissarily at the same folder level, for example /nas/quota/slot_3/home/folders to be renamed> or /nas/quota/slot_3/slot_2/home/folders to be renamed>

Thanks

I guess this would work ok if all folders where in the same folder, inmy case they may be in different subfolders from the same root ?
@jimleslie1977
OK - that's a little more specific. I think I can help.
So you have a list of multiple folders inside locations like:
/nas/quota/slot_3/home/
/nas/quota/slot_3/slot_2/home/


And they all need to be renamed.

Would that be ALL of the folders in those specified directories? or only a selection of them?

Also, is the list compiled in a way that only the top-level directories that need to be deleted are listed.

In other words - if your list contains:
/nas/quota/slot_3/home/someuser/
/nas/quota/slot_3/home/someuser/Documents/
/nas/quota/slot_3/home/someuser/Pictures/

etc etc.
We really only need to identify and rename the top-level directory.
/nas/quota/slot_3/home/someuser/

Because if /nas/quota/slot_3/home/someuser/ is earmarked for deletion, then implicitly everything inside it is also earmarked for deletion. So all of it's sub-directories can be excluded from the list.
If that makes sense?!

You may have already done that, so I might be teaching granny to suck eggs as it were. But if you haven't done that already, do so - because it would help to make the list shorter.

Also - it avoids a potential bug in the script:
Once /nas/quota/slot3/home/someuser/ is renamed to ....someuser_deleteme/ - the script will be unable to find the /someuser/Documents/ subdirectory, because the parent directory has already been re-named - so our renaming script would throw an error.

So I guess the first thing is to make sure your list only contains the paths to the top-level directories you want to rename.

If you want to get rid of the /nas/quota/slot_3/home/ directory AND all of the users, then that will be enough. But if it's only specific directories in there, then instead of that, you would list the user directories to rename.
e.g.
/nas/quota/slot_3/home/someuser/
/nas/quota/slot_3/home/otheruser/
/nas/quota/slot_3/home/user0001/
/nas/quota/slot_3/home/userb/



Once you have a list of all of the paths to the top level directories to rename, you could do something like this:
Bash:
#!/usr/bin/env bash

while read dirPath ; do
  if [[ -d "$dirPath" ]] ; then
    mv "$dirPath" "$dirPath"_deleteme
  fi
done < /path/to/your-list
NOTE: /path/to/your-list should be replaced with the actual path to your list of directories to rename.

And only execute the script if you're 100% certain that the paths in the list are correct! I will accept absolutely no responsibility for anything that gets renamed incorrectly!

The script will read in your list, line by line and if the path is a valid path to a directory - it will use mv to rename it. Appending _deleteme to the end of the name.

I've tested it using a list of directories I just knocked up - so I know that the script works.

Although, if you're going to delete these directories, wouldn't it just make sense to delete them using rm -r?
That way the line containing the mv becomes:
Bash:
    rm -r "$dirPath"
Then the directories in the list are removed instead of renamed.
But again - if you accidentally have the wrong path in your list, you could potentially end up in a world of hurt! I accept no responsibility if you try this with your list and something goes screwy!

Or are you trying to play it safe by simply renaming the directories first? So you can use something later like find, to safely find and remove the renamed directories.
e.g.
Run the script to rename the dirs and then do something like this?:
Bash:
find /nas/quota/ -type d -name "*_deleteme" -delete
Anyway - hopefully this has been of some use to you!
 
Last edited:

captain-sensible

Well-Known Member
Credits
3,597
@JasKinasis yes I know that was just a raw starter idea for something to work from for @jimleslie1977 who should of course do most of the work to get what they want. I do have something that i put in a little more effort in bash that could do with someone to have a quick look over though, if your interested ?
 

captain-sensible

Well-Known Member
Credits
3,597
well first an intro and introduction. Normally a person tries to write a script; it doesn't work so they ask for help. Thats not the case here. I did a slackbuild script that i submitted to slackbuilds.org for latex2html. its been accepted . There are different ways to approach writing a script but there are sections common to all slackbuilds.

For someone wanting to come up with a slackbuild for a package that does not exist in the slackbuild repo it would help if a slackbuild in the way they want it these days was explained section by section.

I have put down my understanding from the process of coming up with a slackbuild for others here: https://docs.slackware.com/howtos:misc:anatomy_of_a_slackbuild

The site main editor did actually do some clarification and should really check it ,but i suspect is now flat out trying to support getting slackware 15 released. I don't want to mislead others , so if you get a minute just have a quick run through please
 

jimleslie1977

New Member
Credits
72
I hate to break it to you @captain-sensible , but that snippet will rename everything in the current directory. Appending _bk to files, directories, sym-links etc etc!

for d in *; sets up a for loop and creates a variable d which will be populated with * (glob for everything) in the current working directory.

Each time through the for loop, the variable d will be populated with the name of a file-system object in the current directory.
The mv command then renames the object to append _mv to the end of it.

So the mv command will effectively rename EVERYTHING in the directory. Not just directories.

Also, if the object is a file with an extension - the file-extension is completely replaced with _bk. So for example file1.txt would become file1_bk.

So for this example, you'd probably be better off putting in a check that the target is a directory. Like this:
Bash:
#!/usr/bin/env bash
for d in * ; do
  if [[ -d "$d" ]] ; then
    mv "$d" "$d"_bk
  fi
done
That way only the directories will be renamed and the files will be left intact.
The files in this directory might be wanted! It may only be the directories that should be removed. So renaming them and losing their original file-extensions could potentially be a bad thing!




@jimleslie1977
OK - that's a little more specific. I think I can help.
So you have a list of multiple folders inside locations like:
/nas/quota/slot_3/home/
/nas/quota/slot_3/slot_2/home/


And they all need to be renamed.

Would that be ALL of the folders in those specified directories? or only a selection of them?

Also, is the list compiled in a way that only the top-level directories that need to be deleted are listed.

In other words - if your list contains:
/nas/quota/slot_3/home/someuser/
/nas/quota/slot_3/home/someuser/Documents/
/nas/quota/slot_3/home/someuser/Pictures/

etc etc.
We really only need to identify and rename the top-level directory.
/nas/quota/slot_3/home/someuser/

Because if /nas/quota/slot_3/home/someuser/ is earmarked for deletion, then implicitly everything inside it is also earmarked for deletion. So all of it's sub-directories can be excluded from the list.
If that makes sense?!

You may have already done that, so I might be teaching granny to suck eggs as it were. But if you haven't done that already, do so - because it would help to make the list shorter.

Also - it avoids a potential bug in the script:
Once /nas/quota/slot3/home/someuser/ is renamed to ....someuser_deleteme/ - the script will be unable to find the /someuser/Documents/ subdirectory, because the parent directory has already been re-named - so our renaming script would throw an error.

So I guess the first thing is to make sure your list only contains the paths to the top-level directories you want to rename.

If you want to get rid of the /nas/quota/slot_3/home/ directory AND all of the users, then that will be enough. But if it's only specific directories in there, then instead of that, you would list the user directories to rename.
e.g.
/nas/quota/slot_3/home/someuser/
/nas/quota/slot_3/home/otheruser/
/nas/quota/slot_3/home/user0001/
/nas/quota/slot_3/home/userb/



Once you have a list of all of the paths to the top level directories to rename, you could do something like this:
Bash:
#!/usr/bin/env bash

while read dirPath ; do
  if [[ -d "$dirPath" ]] ; then
    mv "$dirPath" "$dirPath"_deleteme
  fi
done < /path/to/your-list
NOTE: /path/to/your-list should be replaced with the actual path to your list of directories to rename.

And only execute the script if you're 100% certain that the paths in the list are correct! I will accept absolutely no responsibility for anything that gets renamed incorrectly!

The script will read in your list, line by line and if the path is a valid path to a directory - it will use mv to rename it. Appending _deleteme to the end of the name.

I've tested it using a list of directories I just knocked up - so I know that the script works.

Although, if you're going to delete these directories, wouldn't it just make sense to delete them using rm -r?
That way the line containing the mv becomes:
Bash:
    rm -r "$dirPath"
Then the directories in the list are removed instead of renamed.
But again - if you accidentally have the wrong path in your list, you could potentially end up in a world of hurt! I accept no responsibility if you try this with your list and something goes screwy!

Or are you trying to play it safe by simply renaming the directories first? So you can use something later like find, to safely find and remove the renamed directories.
e.g.
Run the script to rename the dirs and then do something like this?:
Bash:
find /nas/quota/ -type d -name "*_deleteme" -delete
Anyway - hopefully this has been of some use to you!
thats excellent help thankyou so much, just to clarify is the last line correct " done < /path/to/you-list" i mean in particular the "done < " element of the syntax i get the second half is an editable part for me to specify

Thanks again
 

JasKinasis

Well-Known Member
Credits
1,193
well first an intro and introduction. Normally a person tries to write a script; it doesn't work so they ask for help. Thats not the case here. I did a slackbuild script that i submitted to slackbuilds.org for latex2html. its been accepted . There are different ways to approach writing a script but there are sections common to all slackbuilds.

For someone wanting to come up with a slackbuild for a package that does not exist in the slackbuild repo it would help if a slackbuild in the way they want it these days was explained section by section.

I have put down my understanding from the process of coming up with a slackbuild for others here: https://docs.slackware.com/howtos:misc:anatomy_of_a_slackbuild

The site main editor did actually do some clarification and should really check it ,but i suspect is now flat out trying to support getting slackware 15 released. I don't want to mislead others , so if you get a minute just have a quick run through please
@captain-sensible - I'll try to take a look at that when I get a chance. But just to clarify - it's not the actual script that you want help with? - you want feedback WRT the article on creating a slack-build script? Is that correct?

thats excellent help thankyou so much, just to clarify is the last line correct " done < /path/to/you-list" i mean in particular the "done < " element of the syntax i get the second half is an editable part for me to specify

Thanks again
Yes, that syntax is correct. It redirects the input file /path/to/your-list into the while loop. All you need to do is replace /path/to/your-list with the actual path/file-name of your file containing the list of directories to rename.

The while loop reads the file line by line - so you'll need to ensure that there is only one path per line in the file.
e.g.
Code:
/path/to/dir1
/path/to/dir2
/path/to/dir3
etc.

I leave it entirely to you to ensure that the directory paths in the file are correct. I accept absolutely no responsibility for any incorrectly renamed directories.

I've briefly tested the code myself and it also works with directories that have spaces in their names. So I know for a fact that the code works.

Replace /path/to/your-list with the actual path to your list of directories and you're good to go!
 

captain-sensible

Well-Known Member
Credits
3,597
@JasKinasis No not the actual script that is now official here : https://slackbuilds.org/repository/14.2/academic/latex2html/

Although I wrote it ; as you know you can drive a car and still not know how the engine works. For one section i used a block of code knowing basically whats its going to do but not sure i completley get the bash , its the block of code above this paragraph
If i understand the above block of code correctly its using the “find” on the basis of permissions and following symbolic links using the “-L flag”. If i understand this correctly its basically setting directories to 755 in order to enable a “cd” into them and files so that root can read write. If this is true I might have expected
At https://docs.slackware.com/howtos:misc:anatomy_of_a_slackbuild
 

JasKinasis

Well-Known Member
Credits
1,193
@JasKinasis No not the actual script that is now official here : https://slackbuilds.org/repository/14.2/academic/latex2html/

Although I wrote it ; as you know you can drive a car and still not know how the engine works. For one section i used a block of code knowing basically whats its going to do but not sure i completley get the bash , its the block of code above this paragraph At https://docs.slackware.com/howtos:misc:anatomy_of_a_slackbuild
Yes, the code in that section is looking for files or links with a particular set of permissions.

The set of permissions in the first find are typically used for directories (but could also potentially be executable files) and any matches get their permissions set to 755.
The second find is looking for permissions that are typically assigned to regular files and matches are set to 644.

So you're basically correct there!
 


Members online


Latest posts

Top