Лучший способ обработки списков адресов электронной почты

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

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

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


person Community    schedule 09.11.2008    source источник


Ответы (7)


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

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

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

=IF(ISNA(ВПР(ячейка_адреса_эл.почты, Лист2!список_дубликатов_электронной_почты, 1, false), "", (ВПР(ячейка_адреса_эл.почты, Sheet2!email_duplicates_list, 1, false)))

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

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

person Phil.Wheeler    schedule 09.11.2008
comment
Как это решает требования к пробелам и регистру. - person paxdiablo; 10.11.2008
comment
Какое требование? Мы хотим игнорировать различия в регистре (что делает Excel по умолчанию) и пробелы. По общему признанию, вы получите несколько пустых строк, используя приведенное выше предложение, но их можно легко удалить с помощью другого автофильтра. - person Phil.Wheeler; 10.11.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
person Fionnuala    schedule 10.11.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}
person paxdiablo    schedule 09.11.2008

В Питоне примерно так:

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

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));
person Lasse V. Karlsen    schedule 09.11.2008

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

person simon    schedule 10.11.2008

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

cat filea >> fileb # добавить файл a к файлу b

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

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

Теперь вам осталось просто удалить общие электронные письма. Некоторый вариант «diff» должен быть полезен, например: diff newFile fileC > finalFile

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

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

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

person Community    schedule 11.11.2008

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

person Mark Allen    schedule 09.11.2008