Почта. Удаление дубликатов сообщений из локальных почтовых ящиков
Удаление дубликатов сообщений из почтового хранилища типа Maildir. Для mbox тоже можно.
Содержание
1 Программные средства
1.1 mail-deduplicate
- Репозиторий: https://github.com/kdeldycke/mail-deduplicate
- Сайт: https://mail-deduplicate.readthedocs.io/en/latest/
- При первом поиске нашёл данную утилиту.
- К сожалению, собственно функционал по удалению дубликатов писем продекларирован, но пока не реализован.
2 Реализация средствами командной строки
- Принято решение реализовать на коленке.
2.1 Используемое программное обеспечение
- Функционалом удаления почтовых дубликатов обладает утилита
reformail
. - Утилита является частью пакета maildrop, которая в свою очередь является частью почтового сервера Courier.
- Сайт: https://www.courier-mta.org/maildrop/
- Установка:
- Linux
- Gentoo
emerge maildrop
- Gentoo
- Linux
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