[Last Call] Learn how to a build a cloud-first strategyRegister Now

  • Status: Solved
  • Priority: Medium
  • Security: Public
  • Views: 1098
  • Last Modified:

Little batch script to rename directories

Hi folks,

I'd like to rename some special folders on my harddisk. All the folders are looking this way:

[PPP] - ( this text is variable ) - [PPP]

Now I want to exchange all the [PPP] with [TTT] for example, the rest should be left untouched. With my very basics in batch programming I made the following script:

for FILE in "`find / -type d -name "?PPP]*" -print`"
        OLDNAME=`echo -n "$FILE"`
        NEWNAME=`echo -n "$FILE" | sed "s/PPP/TTT/g"`
        mv $OLDNAME $NEWNAME

Unfortunately, this seems not to work. When I do an "echo $OLDNAME" then I get a string with all the oldnamed directories without \n (newline).

Thanks for every helpful input in this :-)
2 Solutions
try this

for FILE in `find / -type d -name "?PPP]*" -print`
SmudoAuthor Commented:
The header must be between quotes "". If it's not, it seems that the spaces in the dir-names are interpreted individually, means that mv gets parameters like




When I use the quotes, I get the following output, when I add an echo $OLDNAME and echo $NEWNAME on the next line:

./test/[PPP] - ( blu blu ) - [PPP]
./test/[PPP] - ( blo blo ) - [PPP]
./[PPP] - ( blah blah ) - [PPP]
./test/[TTT] - ( blu blu ) - [TTT]
./test/[TTT] - ( blo blo ) - [TTT]
./[TTT] - ( blah blah ) - [TTT]
mv: when moving multiple files, last argument must be a directory
Try `mv --help' for more information.

It's strange that all the [PPP] folders are listed on top. Shouldn't they be in order

./test/[PPP] - ( blu blu ) - [PPP]
./test/[TTT] - ( blu blu ) - [TTT]
etc. ?

Your problem is with quotes, or more specifically the lack of them.  If you have spaces in a string, you must quote then in order for it to be seen as a single string.  Also, using a for loop means that elements are split on whitespace (by default), so each part of the directory is split up.  You can use a for loop if you change the IFS value, but I think using a while loop is easier:

find / -type d -name "*\[PPP]*" -print` | while read dir
   newdir=`echo "$dir" | sed 's/PPP/TTT/g'`
   mv "$dir" "$newdir"
one-liner with perl's help:

find /  -name "\[PPP\]*\[PPP\]"|perl -ne'chomp;$o=$_;s/PPP/TTT/g;print "mv \"$o\" \"$_\"\n";'|sh
SmudoAuthor Commented:
Great job! Both worked, Tintin was a bit faster :-)

I just hate to work with spaces in filenames/directories.

Featured Post

Keep up with what's happening at Experts Exchange!

Sign up to receive Decoded, a new monthly digest with product updates, feature release info, continuing education opportunities, and more.

Tackle projects and never again get stuck behind a technical roadblock.
Join Now