NeoMutt mbsync
This guide outlines a robust workflow for moving old emails from a remote IMAP server to a local Maildir archive. This process helps free up space on your email server while ensuring you have a permanent, searchable local copy of your old mail.
The core principle is to maintain a local mirror of your remote mailbox using mbsync, perform the archival (moving files) on the local mirror, and then use mbsync again to propagate the local changes (the "deletions" from the mirrored folder) back to the remote server.
Prerequisites
isyncInstalled: You must haveisync(which provides thembsynccommand) installed on your system.
- mbsync/isync
- notmuch
brew install isyncCreate config file
- Configured
isyncrc: A working~/.config/isyncrcfile must be set up for the target email account. The configuration must includeExpunge Bothto ensure that deletions on the local mirror are synced to the remote server.
两个任意选择一个就行:
~/.mbsyncrc(older style but acceptable)~/.config/isyncrcI use this config file
Example isyncrc Channel configuration:
Channel twine
Far :twine-remote:
Near :twine-local:
Patterns *
Sync All
Expunge Both # <-- This is critical for the workflow
Create Near
Remove Near
SyncState *Making the directories
给你的每个邮箱帐户创建一个本地文件夹:
~/.maildir/twine
~/.maildir/soundfreaq
~/.maildir/biaget下面我们以 twine 为例进行配置。
The Archiving Process
Step 1: Perform a Full Initial Sync
Before making any changes, ensure your local mail mirror is perfectly up-to-date with the remote server. This is a critical safety step.
Run mbsync for your account (replace twine with your channel name if different):
mbsync twineWait for this command to complete successfully. Your local ~/.maildir/twine/ directory now mirrors the remote server.
Step 2: Create the Local Archive Folder
Create a new directory on your local machine to store the archived emails. It's important to create it in the Maildir format, which requires cur, new, and tmp subdirectories.
# Create an archive folder for emails from 2025
mkdir -p ~/.maildir/2025/{cur,new,tmp}Step 3: Move Emails Locally with a Script
The safest way to move emails based on their date is to use a script. This script will find all emails in your local INBOX mirror on or before a specified date and move them to your archive folder.
Create the script file:
bashtouch ~/move_old_emails.sh chmod +x ~/move_old_emails.shAdd the script content: Open
~/move_old_emails.shin a text editor and paste the following code. Remember to adjust the configuration variables at the top if your setup is different.bash#!/bin/bash # --- Configuration --- # Your local synchronized INBOX folder (for the 'twine' account) SOURCE_INBOX="$HOME/.maildir/twine/INBOX" # Your local archive folder ARCHIVE_DIR="$HOME/.maildir/2025" # The cutoff date. Emails on or before this date will be moved. # Format: YYYY-MM-DD CUTOFF_DATE="2025-10-31" # --- Script Logic --- # Convert cutoff date to seconds since epoch for reliable comparison # For macOS/BSD date command: CUTOFF_SECONDS=$(date -j -f "%Y-%m-%d" "$CUTOFF_DATE" "+%s") echo "Archiving emails from $SOURCE_INBOX to $ARCHIVE_DIR" echo "Moving all emails dated on or before $CUTOFF_DATE" echo "---" # Ensure the archive's 'cur' directory exists mkdir -p "$ARCHIVE_DIR/cur" # Find all email files in the INBOX's 'cur' and 'new' subdirectories find "$SOURCE_INBOX/cur" "$SOURCE_INBOX/new" -type f | while read -r email_file; do # Extract the 'Date:' header from the email file date_header=$(grep -i -m 1 '^Date:' "$email_file") if [[ -n "$date_header" ]]; then # Clean up the date string (remove "Date: " prefix and timezone info in parentheses) email_date_str=$(echo "$date_header" | sed -E 's/^Date: //; s/\(.*\)//; s/\s+$//') # Convert the email's date to seconds since epoch # The '-j' flag is for BSD/macOS date; for GNU date, the syntax is different. email_seconds=$(date -j -f "%a, %d %b %Y %H:%M:%S %z" "$email_date_str" "+%s" 2>/dev/null) # If conversion fails, try another common format if [[ -z "$email_seconds" ]]; then email_seconds=$(date -j -f "%d %b %Y %H:%M:%S %z" "$email_date_str" "+%s" 2>/dev/null) fi # Compare the dates if [[ -n "$email_seconds" && "$email_seconds" -le "$CUTOFF_SECONDS" ]]; then echo "Moving: $(basename "$email_file")" mv "$email_file" "$ARCHIVE_DIR/cur/" fi fi done echo "---" echo "Local move complete."Execute the script:
bash~/move_old_emails.sh
The script will move all the targeted email files from ~/.maildir/twine/INBOX/ to ~/.maildir/2025/cur/.
Step 4: Propagate Deletions to the Remote Server
This is the final and irreversible step. Run mbsync again.
mbsync twinembsync will detect that hundreds of files are missing from your local Near mirror (~/.maildir/twine/INBOX). Because of the Expunge Both setting, it will interpret this as a command to delete those same emails from the Far remote server.
Once the command finishes, the old emails are now gone from the server and reside safely in your local archive.
Verification (Optional but Recommended)
You can easily view your local archive in NeoMutt. You can either temporarily change your folder (c) to ~/.maildir/2025 or set up a separate account configuration in NeoMutt that points to your local maildirs for easy access.