Почта. Удаление дубликатов сообщений из локальных почтовых ящиков

Удаление дубликатов сообщений из почтового хранилища типа Maildir. Для mbox тоже можно.

Содержание

1 Программные средства

1.1 mail-deduplicate

2 Реализация средствами командной строки

  • Принято решение реализовать на коленке.

2.1 Используемое программное обеспечение

  • Функционалом удаления почтовых дубликатов обладает утилита reformail.
  • Утилита является частью пакета maildrop, которая в свою очередь является частью почтового сервера Courier.
  • Сайт: https://www.courier-mta.org/maildrop/
  • Установка:
    • Linux
      • Gentoo
        emerge maildrop
        

2.2 Предварительные сведения

  • Почтовый ящик maildir представляет собой дерево каталогов:

    Maildir/cur
    Maildir/new
    Maildir/tmp
    
  • Программа reformail считывает сообщение со стандартного входа, обрабатывает его и записывает результат на стандартный вывод.

  • Извлечение и печать содержимого заголовка:

    reformail -x
    
  • Обнаружение повторяющихся сообщений

    reformail -D len filename
    
    • Параметр -D реализует удаления повторяющихся сообщений во входящей почте.

    • filename — файл кэша длиной примерно len байт.

    • Если сообщение имеет заголовок Message-ID:, который уже находится в файле кэша, повторное сообщение завершается с кодом выхода, равным 0.

    • В противном случае повторное сообщение завершается с кодом выхода, установленным на 1.

    • Например:

      formail -D $((1024*1024*10)) /tmp/idcache
      
      • Кэш установлен в 10 мегабайт.
  • Для работы с форматом mbox используют параметр -s.

    • Файл почтового ящика в формате mbox разбивается на отдельные сообщения.
    • Для каждого сообщения выполняется внешняя программа.
    • Содержание каждого отдельного сообщения будет предоставлено внешней программе на стандартном вводе.

2.3 Реализация для Maildir

2.3.1 Удаление дубликатов

  • Простейший однострочник:
    rm -f /tmp/idcache; for i in cur/*; do reformail -D $((1024*1024*10)) /tmp/idcache <$i && rm $i; done
    
  • Скрипт, удаляющий дубликаты во всех ящиках, синхронизируемых с помощью mbsync (см. Почта. Синхронизация. mbsync)
    #!/bin/bash
    # NAME: dedup-mailbox
    
    MAILDIR=~/Maildir
    
    list_imap=$(grep -e "^IMAPAccount" ~/.mbsyncrc | cut -d" " -f2 | xargs -I {} -n 1 echo {}" ")
    
    for i in ${list_imap}
    do
        list_imapdir=`ls ${MAILDIR}/${i}`
    
        for j in $list_imapdir
        do
            cd "${MAILDIR}/${i}/${j}"
    
            messages_before=`for k in cur/*; do [[ -f $k ]] && reformail -x Message-ID: <$k; done | wc -l`
            messages_unique_before=`for k in cur/*; do [[ -f $k ]] && reformail -x Message-ID: <$k; done | sort -u | wc -l`
    
            rm -f /tmp/idcache
            for k in cur/*
            do
                [[ -f $k ]] && reformail -D $((1024*1024*10)) /tmp/idcache <$k && rm $k
            done
    
            messages_after=`for k in cur/*; do [[ -f $k ]] && reformail -x Message-ID: <$k; done | wc -l`
            messages_unique_after=`for k in cur/*; do [[ -f $k ]] && reformail -x Message-ID: <$k; done | sort -u | wc -l`
    
            echo "Number of messages in ${MAILDIR}/${i}/${j}"
            echo -e "\t" "Total" "\t" "Unique"
            echo -e "Before:\t" $messages_before "\t" $messages_unique_before
            echo -e "After:\t"  $messages_after  "\t" $messages_unique_after
        done
    
    done
    

2.3.2 Необязательные проверки

  • Перед и после удаления проверьте полное количество сообщений:
    for i in cur/*; do reformail -x Message-ID: <$i; done | wc -l
    
  • Также проверьте количество уникальных сообщений:
    for i in cur/*; do reformail -x Message-ID: <$i; done | sort -u | wc -l
    

2.4 Реализация для mbox

2.4.1 Удаление дубликатов

  • Скрипт, вызывающий программу обработки для каждого сообщения из mbox:
    #!/bin/sh
    # NAME: dedup-mbox
    # INPUT: $1 = mbox
    # OUTPUT: nmbox (файл с удалёнными дубликатами сообщений)
    
    # Delete temporary files
    rm -f /tmp/tmpmail /tmp/idcache nmbox
    
    # reformail-mbox.sh is called for each mail
    cat $1 | reformail -s ./reformail-mbox.sh
    
  • Основной скрипт для дедупликации:
    #!/bin/bash
    # NAME: reformail-mbox.sh
    # INPUT: stdin: a email
    # called by dedup-mbox
    
    TM=/tmp/tmpmail
    if [ -f $TM ]
    then
        echo error!
        exit 1
    fi
    cat > $TM
    
    # mbox format, each mail end with a blank line
    echo "" >> $TM
    
    cat $TM | reformail -D $((1024*1024*10)) /tmp/idcache
    
    # if this mail isn't a dup (reformail return 1 if message-id is not found)
    if [ $? != 0 ]
    then
        # each mail shall have a message-id
        if grep -q -i '^message-id:' $TM
        then
            cat $TM >> nmbox
        fi
    fi
    
    rm $TM
    

Дмитрий Сергеевич Кулябов
Дмитрий Сергеевич Кулябов
Профессор кафедры теории вероятностей и кибербезопасности

Мои научные интересы включают физику, администрирование Unix и сетей.

Похожие