Need help with bash script to parse / create folders

Frosty555
Frosty555 used Ask the Experts™
on
I need to write a script that parses a list of folders and creates some "missing" folder names.

The background to this is that I am using imapsync to sync a google imap mailbox to a local ubuntu machine's maildir running dovecot. The script works pretty good with one issue:

Sometimes I end up with a sequence of folders in the maildir that look like this:

.Drafts
.Sent Items
.School
.Facebook
.Bills.Hydro
.Bills.Gas.Outstanding
.Bills.Gas.Paid
.Bills.Cell.Outstanding
.Bills.Cell.Paid

The issue with the example folder list above is that some of the "parent" folders in the tree do not exist. In this case, the following folders *should* exist, but haven't been created

.Bills
.Bills.Gas
.Bills.Cell

The reason why they haven't been created is because technically no messages were actually inside those labels in Google. This doesn't *actually* cause any real issues with dovecot, but it makes the folders not display correctly in SquirrelMail.

So I'm trying to write a bash script which will create the above folders. Basically the algorithm for what it needs to do is this:

1) Loop through all the "dot" folders (folders beginning with .) in /home/jsmith/maildir/
2) Skip "." and ".."
3) For every folder it finds:
         a) Parse the string and determine a list of "parent" folder names, e.g. if the folder name is

                 .Bill.Hydro.Paid

             The parent names that need to be examined are

                  .Bills.Hydro
                  .Bills

         b) For every "parent name" calculated in a), check if it exists. If it doesn't, create it.

No need for optimizations - it can do this to *every* folder it finds and it can repeat a lot of work checking folders that already exist over and over. The script will run only once or twice a day, so no big deal.

I'm pretty good with Bash, but the string parsing and looping through folders (3 and 3a) has got me stumped. There's a few important issues:

- Folders CAN have spaces in them, so a basic FOR loop won't work. At the very least, the IFS variable needs to be set to delimit on \n instead of whitespace.
- I need to loop through all folders beginning with a dot, but SKIP "." and ".."
- I have no idea how to parse the string using bash

Can anyone help me write this script?

Doesn't necessarily need to be in Bash - it can be in Perl if that helps... but I think Bash is probably the best candidate.

Thanks!
Comment
Watch Question

Do more with

Expert Office
EXPERT OFFICE® is a registered trademark of EXPERTS EXCHANGE®
Top Expert 2011

Commented:
for ".Bill.Hydro.Paid", should it create
/home/jsmith/maildir/.Bill/.Hydro/.Paid
or
/home/jsmith/maildir/Bill/Hydro/Paid
Top Expert 2011

Commented:
Please also give two example of folder name with "space" and (dot)
Top Expert 2011

Commented:
Assume /home/jsmith/maildir/.Bill/.Hydro/.Paid is what you want
#!/bin/bash

DIR_LIST_FILE=/tmp/dir_list.txt

cd /home/jsmith/maildir/
/bin/ls -1d .* | egrep -v '\.$|\.\.$' > $DIR_LIST_FILE  # list the 1 dir name per line 

while "$ITEM"
do
  if [ -d "$ITEM" ]; then
     NEW_DIR="`echo $ITEM | sed 's/\./\/\./g'`"  # replace "." with "/."
     mkdir -p ./"${NEW_DIR}"  # mkdir -p : no error if existing, 
                              # make parent directories as needed
  fi
done < $DIR_LIST_FILE

Open in new window

Author

Commented:
Hi wesly,

Sorry I didn't mean .Bill/.Hydro/.Paid, rather instead, three folders at the root:

.Bill
.Bill.Hydro
.Bill.Hydro.Paid

This is how maildir structures their folders.

All folders will being with a ".", and use "." as the separator character. Some folders may have spaces, for example, if a folder is found with this name:

"/home/jsmith/maildir/.Christmas Emails.2010.Debby Jones"

The folders that need to be created are:

"/home/jsmith/maildir/.Christmas Emails"
"/home/jsmith/maildir/.Christmas Emails.2010"
"/home/jsmith/maildir/.Christmas Emails.2010.Debby Jones"
Top Expert 2011
Commented:
Try this one, verified with the following dir list
---------
.Drafts
.Sent Items
.School
.Facebook
.Bills.Hydro
.Bills.Gas.Outstanding
.Bills.Gas.Paid
.Bills.Cell.Outstanding
.Bills.Cell.Paid
.Christmas Emails.2010.Debby Jones

#!/bin/bash

DIR_LIST_FILE=/tmp/dir_list.txt

cd /home/jsmith/maildir/
/bin/ls -1d .* | egrep -v '\.$|\.\.$' > $DIR_LIST_FILE  # list the 1 dir name per line 

while read ITEM
do
  if [ -d "$ITEM" ]; then
     DIR_NO=`echo $ITEM | awk -F'.' '{print NF}'`
     COUNT=2
     DIR_NAME=''
     while [ $DIR_NO -ge 2 ]
     do
       DIR1=`echo $ITEM | awk -F'.' -v var=$COUNT '{print $var}'`
       DIR_NAME="${DIR_NAME}"."${DIR1}"
       mkdir -p "${DIR_NAME}"
       ((COUNT++))
       ((DIR_NO--))
     done
  fi
done < $DIR_LIST_FILE

Open in new window

Author

Commented:
It looks like it is working pretty good! I Added a few debug echo's and an if statement to not call mkdir unless the folder actually didn't exist, and aside from that it's working perfectly. Thanks!

Do more with

Expert Office
Submit tech questions to Ask the Experts™ at any time to receive solutions, advice, and new ideas from leading industry professionals.

Start 7-Day Free Trial