Вчера обратился один товарищ, столкнувшийся с проблемой переноса контактов из смартфона на WM6 под новый Андроидофон. После недели тщетных попыток он опустил руки и передал csv-файл, полученный из аутлука, к которому ему довольно просто удалось подключить записную книжку телефона.
В результате слегка погуглив, но не найдя простого решения пришлось налабать скриптик на великом и могучем, который создает vcf-файл контактов, который в свою очередь легко импортируется в Андроид стандартными средствами телефона.
Исходные данные
Собственно то, с чем пришлось столкнуться.
CSV
CSV-файл — обычный текстовый файл в котором каждая строка представляет собой строку таблицы данных, а столбцы внутри строки разделяются символом-разделителем, который может выбираться пользователем и обычно представляет собой знак табуляции, точку с запятой, запятую и т.п. В первой строке зачастую присутствуют не значения данных, а имена полей.
При экспорте из Outlook необходимо выбрать все поля и разрешить помещать названия полей в первой строке (возможно это включено по умолчанию).
Обращение; Имя; Отество; Фамилия; Суффикс; Организация; Отдел; Должность; Улицарабадрес; Улица2рабадрес; Улица3рабадрес; Городрабадрес; Областьрабадрес; Индексрабадрес; Странарабадрес; Улицадомадрес; Улица2домадрес; Улица3домадрес; Городдомадрес; Областьдомадрес; Потовыйкоддом; Странадомадрес; Улицадругойадрес; Улица2другойадрес; Улица3другойадрес; Городдругойадрес; Областьдругойадрес; Индексдругойадрес; Странадругойадрес; Телефонпомощника; Рабоийфакс; Рабоийтелефон; Телефонраб2; Обратныйвызов; Телефонвмашине; Основнойтелефонорганизации; Домашнийфакс; Домашнийтелефон; Телефондом2;ISDN; Телефонпереносной; Другойфакс; Другойтелефон; Пейджер; Основнойтелефон; Радиотелефон; Телетайптелефонститрами; Телекс; Важность; Вебстраница; Годовщина; Деньрождения; Дети; Имяпомощника; Инициалы; Категории; Клюевыеслова; Кодорганизации; Линыйкод; Отложено; Пол; Пользователь1; Пользователь2; Пользователь3; Пользователь4; Пометка; Потовыйящикдомадрес; Потовыйящикдругойадрес; Потовыйящикрабадрес; Профессия; Расположение; Расположениекомнаты; Расстояние; Руководитель; СведенияодоступностивИнтернете; Серверкаталогов; Супруга; Сет; Сета; Хобби;_астное; Адресэлпоты; Типэлпоты; Краткоеимяэлпоты; Адрес2элпоты; Тип2элпоты; Краткое2имяэлпоты; Адрес3элпоты; Тип3элпоты; Краткое3имяэлпоты; Язык[CRLF]
; Кредит;;Bee Line Счет;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;067404;;;067404;;;;;;;; Обычная;;;;;; К.B.L.С.; Служебные;;;;; Не определен;;;;; Обычная;;;;;;;;;;;;;;; ЛОЖЬ;;;;;;;;;;[CRLF]
Прочие записи
vCard
Это формат визитной карточки. В Андроидофонах это основной формат обмена контактами. Если вы пытаетесь отправить контакт по почте или SMS то телефон прицепит именно vcf-карточку. Прелесть формата, в том что в одной карточке (файле) можно объединять несколько контактов.
BEGIN:VCARD
VERSION:3.0
CATEGORIES: Служебные
N:Bee Line Счет; Кредит
TEL;TYPE=cell:067404
TEL;TYPE=home:067404
END:VCARD
Скрипт-конвертер
Скрипт написан на удобном, простом, легковесном, кросс-платформенном, и еще куча разных эпитетов awk. В начале указывается разделитель полей внутри csv (мне попался csv с точкой-с-запятой). Далее задается карта отображения полей csv в поля vCard в виде массива KEYS. В общем-то это все настройки, которые должны работать по умолчанию.
BEGIN {
FS = ";"
KEYS["Фамилия"] = "N.1";
KEYS["Имя"] = "N.2";
KEYS["Отество"] = "N.3";
KEYS["Обращение"] = "N.4";
KEYS["Суффикс"] = "N.5";
KEYS["Организация"] = "ORG.1";
KEYS["Отдел"] = "ORG.2";
KEYS["Должность"] = "TITLE";
KEYS["Улицарабадрес"] = "ADR;TYPE=work.2";
KEYS["Улица2рабадрес"] = "ADR;TYPE=work.2";
KEYS["Улица3рабадрес"] = "ADR;TYPE=work.2";
KEYS["Городрабадрес"] = "ADR;TYPE=work.3";
KEYS["Областьрабадрес"] = "ADR;TYPE=work.4";
KEYS["Индексрабадрес"] = "ADR;TYPE=work.5";
KEYS["Странарабадрес"] = "ADR;TYPE=work.6";
KEYS["Потовыйкоддом"] = "ADR;TYPE=home.1";
KEYS["Улицадомадрес"] = "ADR;TYPE=home.2";
KEYS["Улица2домадрес"] = "ADR;TYPE=home.2";
KEYS["Улица3домадрес"] = "ADR;TYPE=home.2";
KEYS["Городдомадрес"] = "ADR;TYPE=home.3";
KEYS["Областьдомадрес"] = "ADR;TYPE=home.4";
KEYS["Индексдомадрес"] = "ADR;TYPE=home.5";
KEYS["Странадомадрес"] = "ADR;TYPE=home.6";
KEYS["Улицадругойадрес"] = "ADR;TYPE=postal.2";
KEYS["Улица2другойадрес"] = "ADR;TYPE=postal.2";
KEYS["Улица3другойадрес"] = "ADR;TYPE=postal.2";
KEYS["Городдругойадрес"] = "ADR;TYPE=postal.3";
KEYS["Областьдругойадрес"] = "ADR;TYPE=postal.4";
KEYS["Индексдругойадрес"] = "ADR;TYPE=postal.5";
KEYS["Странадругойадрес"] = "ADR;TYPE=postal.6";
KEYS["Телефонпомощника"] = "TEL;TYPE=pager";
KEYS["Рабоийфакс"] = "TEL;TYPE=work;TYPE=fax";
KEYS["Рабоийтелефон"] = "TEL;TYPE=work";
KEYS["Телефонраб2"] = "TEL;TYPE=work";
KEYS["Обратныйвызов"] = "TEL;TYPE=X-EVOLUTION-CALLBACK";
KEYS["Телефонвмашине"] = "TEL;TYPE=car";
KEYS["Основнойтелефонорганизации"] = "TEL;TYPE=work";
KEYS["Домашнийфакс"] = "TEL;TYPE=home;TYPE=fax";
KEYS["Домашнийтелефон"] = "TEL;TYPE=home";
KEYS["Телефондом2"] = "TEL;TYPE=home";
KEYS["ISDN"] = "TEL;TYPE=isdn";
KEYS["Телефонпереносной"] = "TEL;TYPE=cell";
KEYS["Другойфакс"] = "TEL;TYPE=fax";
KEYS["Другойтелефон"] = "TEL";
KEYS["Пейджер"] = "TEL;TYPE=pager";
KEYS["Основнойтелефон"] = "TEL";
KEYS["Радиотелефон"] = "TEL;TYPE=pcs";
KEYS["Телетайптелефонститрами"] = "TEL;TYPE=msg";
KEYS["Телекс"] = "TEL;TYPE=msg";
KEYS["Важность"] = "";
KEYS["Вебстраница"] = "URL";
KEYS["Годовщина"] = "X-ANNIVERSARY";
KEYS["Деньрождения"] = "BDAY";
KEYS["Дети"] = "";
KEYS["Имяпомощника"] = "X-ASSISTANT";
KEYS["Инициалы"] = "";
KEYS["Категории"] = "CATEGORIES";
KEYS["Клюевыеслова"] = "NOTE";
KEYS["Кодорганизации"] = "";
KEYS["Линыйкод"] = "";
KEYS["Отложено"] = "";
KEYS["Пол"] = "";
KEYS["Пользователь1"] = "";
KEYS["Пользователь2"] = "";
KEYS["Пользователь3"] = "";
KEYS["Пользователь4"] = "";
KEYS["Пометка"] = "";
KEYS["Потовыйящикдомадрес"] = "";
KEYS["Потовыйящикдругойадрес"] = "";
KEYS["Потовыйящикрабадрес"] = "";
KEYS["Профессия"] = "";
KEYS["Расположение"] = "";
KEYS["Расположениекомнаты"] = "";
KEYS["Расстояние"] = "";
KEYS["Руководитель"] = "";
KEYS["СведенияодоступностивИнтернете"] = "";
KEYS["Серверкаталогов"] = "";
KEYS["Супруга"] = "X-SPOUSE";
KEYS["Сет"] = "";
KEYS["Сета"] = "";
KEYS["Хобби"] = "";
KEYS["_астное"] = "";
KEYS["Адресэлпоты"] = "EMAIL;TYPE=internet";
KEYS["Типэлпоты"] = "";
KEYS["Краткоеимяэлпоты"] = "";
KEYS["Адрес2элпоты"] = "EMAIL;TYPE=internet";
KEYS["Тип2элпоты"] = "";
KEYS["Краткое2имяэлпоты"] = "";
KEYS["Адрес3элпоты"] = "EMAIL;TYPE=internet";
KEYS["Тип3элпоты"] = "";
KEYS["Краткое3имяэлпоты"] = "";
KEYS["Язык"] = "";
}
FNR == 1 {
for (i = 1; i <= NF; i++) {
k = KEYS[$i];
if ("" != k) {
MAPS[i] = k;
}
}
}
FNR != 1 {
delete PROPS;
for (i = 1; i <= NF; i++) {
k = MAPS[i];
if (("" != $i) && ("" != k)) {
PROPS[k] = $i;
}
}
n = asorti(PROPS, SKEYS);
if (n > 0) {
l = "";
print("BEGIN:VCARD");
printf("VERSION:3.0");
for (i = 1; i <= n; i++) {
k = SKEYS[i];
v = PROPS[k];
if (2 == split(k, a, ".")) {
k = a[1];
x = 0 + a[2];
}
else {
x = 1;
}
if (l != k) {
l = k;
m = 1;
printf("rn%s:", l);
}
while (m < x) {
m++;
printf(";");
}
printf("%s", v);
}
print("rnEND:VCARD");
}
}
function die(str) {
print "Error at " FILENAME ":" FNR " " str
exit
}
function warn(str) {
print "Warning at " FILENAME ":" FNR " " str
}
Как запускать
Запускать скрипт из под интерпретатора awk следующим образом:
gawk -f outlook2vcard.awk inputfile.csv >outputfile.vcf
В качестве входных файлов можно указать несколько файлов csv, тогда они будут объединены.
Ложка дегтя
Скрипт автоматически не преобразует кодировку кириллицы в UTF-8, который является родным для Андроида. Этот заключительный аккорд надо сделать вручную либо с помощью iconv для юниксоидов, она же кстати есть и под gnuwin32, либо обычным блокнотом (notepad.exe) для форточек, открыв файл, а затем сохранив с новым именем (Save As...) и выбрав кодировку UTF-8 под именем нового файла.
Импорт в телефон
Способ прост и описан в куче блогов и форумов, но не поленюсь и приведу еще раз. Полученный файл с расширением vcf необходимо положить на карту памяти Андроидофона. Затем войти в контакты, нажать кнопку меню и выбрать «Импорт/Экспорт — Импорт с карты памяти», вуаля.
Автор: ma5ter