Лучший способ обработки списков адресов электронной почты - PullRequest
2 голосов
/ 10 ноября 2008

У меня есть 3 текстовых файла (A, B и C), каждый с несколькими сотнями адресов электронной почты. Я хочу объединить список A и список B в один файл, игнорируя различия в регистре и пробеле. Затем я хочу удалить все электронные письма в новом списке, которые находятся в списке C, снова игнорируя различия в регистре и пробеле.

Обычно я выбираю язык программирования C ++, но кажется, что он плохо подходит для этой задачи. Существует ли язык сценариев, который мог бы выполнять это (и аналогичные задачи) в относительно короткие строки?

Или уже есть программное обеспечение (бесплатное или коммерческое), которое позволило бы мне это сделать? Можно ли это сделать в Excel, например?

Ответы [ 7 ]

3 голосов
/ 10 ноября 2008

Самый быстрый способ сделать это, вероятно, не обязательно требует кодирования. Вы можете импортировать файлы A и B в Excel на одном листе, а затем (при необходимости) выполнить фильтр в этом результирующем списке адресов, чтобы удалить любые дубликаты.

Следующим шагом будет импорт файла C во второй лист. На третьем листе вы должны выполнить VLOOKUP, чтобы выбрать все адреса в вашем первом списке и удалить их, если они есть в вашем «Списке C».

VLOOKUP будет выглядеть примерно так:

= IF (ISNA (VLOOKUP ( email_address_cell , Sheet2! email_duplicates_list , 1, false), "", (VLOOKUP ( email_address_cell , Sheet2! email_duplicates_list , 1, false)))

Я также включил проверку, чтобы увидеть, возвращает ли формула ошибку «Значение не доступно», и в этом случае в ячейке просто отображается пустое значение. Оттуда вам просто нужно удалить пробел, и вот ваш окончательный список.

Теперь, сказав все это, вы все равно можете сделать макрос VBA, чтобы сделать то же самое, но, возможно, немного очистить списки, в зависимости от того, что вам нужно. Надеюсь, это поможет!

2 голосов
/ 10 ноября 2008

Как упоминалось в Excel, вы также можете делать подобные вещи с Jet и VBScript.

Set cn = CreateObject("ADODB.Connection")
strCon = "Provider=Microsoft.Jet.OLEDB.4.0;Data Source=c:\Docs\;" _
& "Extended Properties=""text;HDR=No;FMT=Delimited"";"

cn.Open strCon

strSQL = "SELECT F1 Into New.txt From EmailsA.txt " _
    & "WHERE UCase(F1) Not IN (SELECT UCase(F1) From EmailsC.txt)"
cn.Execute strSQL

strSQL = "INSERT INTO New.txt ( F1 ) SELECT F1 FROM EmailsB.txt " _
    & "WHERE UCase(F1) Not IN (SELECT UCase(F1) From EmailsC.txt)"
cn.Execute strSQL
2 голосов
/ 10 ноября 2008

Для обработки текста того типа, который вы описываете, идеально подходит либо perl, либо python.

Вы можете использовать ассоциативные массивы (в данном случае массивы со строковым индексом) для хранения адресов электронной почты в списке.

Используйте в качестве ключа адрес электронной почты в нижнем регистре без пробелов и реальный адрес электронной почты в качестве значения.

Затем необходимо прочитать и сохранить первый файл, прочитать и сохранить второй (который перезапишет адреса электронной почты с тем же ключом), затем прочитать третий файл и удалить записи из списка с этим ключом.

То, что вам остается, это список, который вы хотите (A + B - C).

Псевдокод здесь:

set list to empty
foreach line in file one:
    key = unwhitespace(tolowercase(line))
    list{key} = line
foreach line in file two:
    key = unwhitespace(tolowercase(line))
    list{key} = line
foreach line in file three:
    key = unwhitespace(tolowercase(line))
    if exists(list{key})
        delete list{key}
foreach key in list:
    print list{key}
1 голос
/ 11 ноября 2008

К сожалению, этот ответ, вероятно, вам не поможет, но если бы вы использовали Unix (например, Linux), вы могли бы сделать что-то вроде:

cat filea >> fileb # добавление файла a в файл b

сортировка fileb | uniq> newFile # newFile теперь содержит слияние файла a и файла b с отсортированными и уникальными адресами электронной почты

Все вышеперечисленное можно выполнить в одну строку следующим образом: cat filea >> fileb | сортировать | uniq> newFile

Теперь вам осталось просто удалить обычные письма. Там может быть полезен вариант «diff», например: файл diff newFileC> finalFile

diff выдаст вам список различий между этими двумя файлами, поэтому выводом в "finalFile" должен быть список писем, которые находятся в "newFile" (объединение A & B), но НЕ в fileC. Параметры различных инструментов позволяют игнорировать пробелы и регистр. Мне бы пришлось немного поиграть с этим, чтобы понять все правильно, но вышеизложенное является общей идеей.

Раньше у меня был дополнительный компьютер под управлением Linux с единственной целью - выполнять описанные выше действия, что является хлопотным делом под Windoze, но легким делом на операционных системах типа Unix. Когда мое оборудование умерло, я так и не смог собрать еще одну коробку Linux.

Я полагаю, что инструментарий MKS для Windoze, вероятно, содержит все перечисленные выше утилиты.

1 голос
/ 10 ноября 2008

Я думаю, что ответы выше, ответьте на технический вопрос КАК; остается только рассмотреть, сколько раз вам придется выполнять задание. Если это одноразовая вещь и вам удобнее работать с Excel, начните там. Если вы знаете, что вам придется выполнять эту задачу как минимум дважды, а может и больше, тогда лучше всего написать код сценария или исполняемого файла.

1 голос
/ 10 ноября 2008

В Python что-то вроде этого:

Обратите внимание, что это будет писать письма в нижнем регистре к окончательному выводу. Если это не так, тогда потребуется решение на основе словаря.

def read_file(filename):
    with file(filename, "r") as f:
        while True:
            line = f.readline();
            if not line:
                break;
            line = line.rstrip();
            if line:
                yield line;

def write_file(filename, lines):
    with file(filename, "w") as f:
        for line in lines:
            f.write(line + "\n");

set_a = set((line.lower() for line in read_file("file_a.txt")));
set_b = set((line.lower() for line in read_file("file_b.txt")));
set_c = set((line.lower() for line in read_file("file_c.txt")));

# Calculate (a + b) - c
write_file("result.txt", set_a.union(set_b).difference(set_c));
0 голосов
/ 10 ноября 2008

Excel может сделать это, как указано выше. Наиболее подходящий язык программирования - Perl.

...