Maildir to zmmailbox with bash

Revision as of 17:54, 20 December 2009 by Nervous (talk | contribs)

What's new

I decided to rewrite Jarosław's script to fix a few bugs I stumbled upon while migrating my bare-Postfix server to Zimbra, namely:

  • all folders were merged into the main folder due to a bug in the script (hint: '=' instead of '==').
  • folders with spaces in their name were not imported and caused an error
  • import messages from accounts across multiple domains, if needed
  • made the code readable
  • no need for two loops

How to use

The script expects to find the mailboxes in the current path! The structure of maildirs must be as follows:


After the script has run, every zimbra user will have a subfolder in his mailbox called 'old-mbox' (feel free to change the name at the beginning of the script). The hierarchy of subfolders is maintained under old-mbox.

The code


# Postfix virtual transport -> Zimbra mailbox migration
# written by NERvOus (

# base folder where msgs will be imported

echo You must run $0 from inside /var/mail/virtual directory
echo $0 expects to find the mailboxes in the current path!
echo The structure of maildirs must be as follows:
echo "domain/username/{cur|new|tmp}"
echo "domain/username/subfolder1/{cur|new|tmp}"
echo "domain/username/subfolder2/{cur|new|tmp}"
echo ...
echo All folders will be stored in a subfolder called $BFOLDER
echo The hierarchy of subfolders will be maintained under $BFOLDER.
echo Press Enter to start, CTRL+C to abort.

# handle folders with a space inside, they are more common than you may
# think

for p in $(find . -type d -name cur); do
        DOMAIN=`echo $p | cut -d'/' -f2`
        UNAME=`echo $p | cut -d'/' -f3`
        DIRNAME=`echo $p | cut -d'/' -f4`
        # this may fail, if folder already exists. Who cares. Ignore the
        # error.
        echo createFolder /$BFOLDER | $ZMMBOX -z -m $UNAME@$DOMAIN
        if [ "$DIRNAME" == "cur" ]; then
                echo Importing INBOX folder for $UNAME@$DOMAIN from $BDIR/$DOMAIN/$UNAME/ 1>&2
                # we are importing the top level folder
                echo addMessage /$BFOLDER $BDIR/$DOMAIN/$UNAME/cur | $ZMMBOX -z -m $UNAME@$DOMAIN
                echo addMessage /$BFOLDER $BDIR/$DOMAIN/$UNAME/new | $ZMMBOX -z -m $UNAME@$DOMAIN
                DIRNAME=$(echo $DIRNAME | sed -e 's/\/cur$//')
                echo Importing folder $DIRNAME for $UNAME@$DOMAIN from $BDIR/$DOMAIN/$UNAME/$DIRNAME 1>&2
                echo createFolder \'/$BFOLDER/$DIRNAME\' | $ZMMBOX -z -m $UNAME@$DOMAIN
                echo addMessage \'/$BFOLDER/$DIRNAME\' \'$BDIR/$DOMAIN/$UNAME/$DIRNAME/cur\' | $ZMMBOX -z -m $UNAME@$DOMAIN
                echo addMessage \'/$BFOLDER/$DIRNAME\' \'$BDIR/$DOMAIN/$UNAME/$DIRNAME/new\' | $ZMMBOX -z -m $UNAME@$DOMAIN

Jump to: navigation, search