tags:

views:

387

answers:

5

On our Linux file server (RedHat Enterprise) we have some folders that we need to rename that have client work in them. The old folder format (ones that need to be changed) was clientcode_jobnumberjobname. The new format is clientcode_jobnumber_jobname. We basically need to change the old folder names by adding the extra underscore to the foldername between the jobnumber and jobname. We also have all the new folder structures that are being created to display in the new format so these will not need to be changed. The job number is always 1 letter followed by 4 numbers. The client code is 3-4 letters depending on the client. The job name is different for every job. The folders are all located at clients/clientname/jobs/clientcode/"folder that needs to be renamed" (just an example of how deep the script will have to go into the structure). It will need to do this for each clientcode under each client. How would I setup a script to do this? Any help would be greatly apprciated. We have thousands of these folders that we need to rename.

+7  A: 

There are a few commands that act like sed on file names; try mmv (or the perl variant of rename, aka prename or rename.PL, which you may not find on RHEL).

As a bonus, both have a -n option (no-act), so you can check what you're going to do isn't going to clobber things or lose information.

Tobu
+1 for resisting the desire to code it up.
Noufal Ibrahim
The RH rename is different from Debian rename, and won't work here.
Ignacio Vazquez-Abrams
It's sometimes called `prename`.
Dennis Williamson
Beware: there are at least two entirely different "rename"s and the one that ships with Red Hat will overwrite existing files without warning. Larry Wall's perl-based version won't do this (ships with Ubuntu).
Ryan Bright
Edited. Bonus bonus: `vidir`, part of `moreutils` on debian/ubuntu.
Tobu
A: 
for entry in * ; do
  if [ ! -d "$entry" ] ; then
    continue
  fi
  jobname="${entry##*_?????}"
  dirbase="${entry%$jobname}"
  if [ -z "$dirbase" -o -z "$jobname" ] ; then
    echo "Error with '$entry'"
    continue
  fi
  mv "$entry" "${dirbase}_$jobname"
done
Ignacio Vazquez-Abrams
A: 

Hi,

perhaps it's just me, but i don't quite understand exactly how the directory structure looks like, could you please provide an example within some code tags.

And perhaps this should be on serverfault.com (but i guess a #!/bin/sh script counts as programming)

EDIT: Noufal Ibrahim, resisting? It's about using a way that works across all POSIX-compliant versions, or Linux, perhaps im old, but the Solaris machines i have don't include rename or mmv. Hence, such a solution is not possible.

Thomas David
A: 

since you say the name format is highly structured and everything is under a single parent (either as direct or indirect children..not sure from what you have mentioned), I would suggest this:

Create a regular expression for the folder name and write a small perl script that would match the name of the contents of the target folder (under which yo have the folders to be renamed) against the regular expression. once you have the matches, rename the folder to the new name. Perl makes all this easy.

In case you decide to pursue this approach and just in case, you do not know Perl and are wondering where to start and provided you are interested in doing some learning along the way, I would suggest you read through the book "Minimal Perl"...a fast and interesting way of learning the monstrous language and putting it to use for things similar to what you need now.

Hope this helps.

Aadith
A: 
find /path/clients -type d -name "*_?[0-9][0-9][0-9][0-9]*" | while IFS= read -r DIR
do
    dir=${DIR##*/}
    base=${DIR%/*}
    IFS="_"
    set -- $dir
    front=$1
    back=$2
    jobname=${back#?????}
    jobnum=${back%$jobname}
    newname="${front}_${jobnum}_${jobname}"
    echo mv "$DIR" "$base/$newname"
done
ghostdog74