Перевод кода и метаданных конфигурации на английский язык: часть 2

Публикация № 1219589

Разработка - Инструментарий разработчика

LanguageTool РегулярныеВыражения

Практический пример подготовки словаря для перевода кода и модели конфигурации УНФ 1.6 на английский язык с использованием существующих словарей и плагина EDT Language Tool. В статье приводятся готовые скрипты и алгоритмы сборки и нормализации словаря.

 

Введение

В первой части статьи был составлен русско-английский словарь для перевода метаданных с помощью сопоставления двух конфигураций: УНФ и её переведённого на английский язык "родственника" Company Management. А сейчас рассмотрим составление более обширного словаря путём компиляции других имеющихся переводов.

Будем использовать несколько существующих словарей перевода кода 1С на английский язык, они составлялись в разное время и разными людьми. Качество словарей тоже отличается, какие-то слова переведены по-разному, в некоторых словарях есть дубли.

В статье показано как можно собрать информацию из разных источников и составить словарь для перевода конкретной конфигурации на примере УНФ 1.6. Предлагаются подходы и инструменты для нормализации словаря.

Приведённая методика будет полезна в дальнейшей работе по переводу конфигураций.

1. Использованные словари

  • 0_dict_uid.txt Словарь метаданных УНФ - СМ составленный по uuid в первой части статьи. 4 800 строк
  • 1_dictionary_platform.xml Словарь перевода платформы. Не самый свежий, но может быть полезен. 8 500 строк
  • 2_DictSB_1.5_23.03.2016.txt Словарь перевода УНФ 1.5 на английский (SmallBusiness). 294 000 строк
  • 3_SSL_slovar.txt Словарь перевода английской БСП. 144 000 строк
  • 4_SSL_auto.xlsx Cловарь перевода кода БСП 3. 25 000 строк

Language tool содержит встроенный словарь платформы, поэтому файл 1_dictionary_platform.xml не используем.

Далее воспользуемся следующим подходом: с помощью плагина Language Tool выгрузим все переводимые строки из УНФ 1.6 и последовательно переведём их по имеющимся словарям. Поскольку в дальнейшем мы планируем объединять CM и УНФ, хочется чтобы перевод УНФ максимально совпадал с переводом CM. Поэтому наибольший приоритет будут иметь словари 0_dict_uid.txt и 2_DictSB_1.5_23.03.2016.txt.

Предварительно отфильтруем словари 2_DictSB_1.5_23.03.2016.txt и 3_SSL_slovar.txt. Поскольку эти файлы помимо перевода идентификаторов (имён) содержат и перевод интерфейсных строк, выполним очистку от ненужных данных с помощью приведённых скриптов: 

  • оставляем строки с кириллицей (удаляем тривиальные строки типа ActionsPanel ActionsPanel)
    grep -P '^.*?[а-яА-Я].*?\t' 'Dict.txt' > 'Dict filtered.txt'
  • удаляем строки с пустым переводом (после табуляции) 
    grep -P '\t.*?[a-zA-Z].*?\r' 'Dict filtered.txt' > 'DictSB filtered 2.txt'
  • удаляем строки с пробелами (т.е. интерфейсные строки) 
    grep -v ' ' '2. DictSB filtered 2.txt' | sed 's/\.//g' > 'DictSB NoDotsAndSpaces.txt'

     

Размер словарей после фильтрации: 2_DictSB_1.5_23.03.2016.txt 157 000 строк, 3_SSL_slovar.txt 63 000 строк

2. Объединение словарей

Выгружаем из EDT все имена и идентификаторы УНФ 1.6 требующие перевода в файл common_en.txt.
Для этого нажимаем правой кнопкой на проекте в окне навигатора, выбираем Translation - Generate translation strings



В открывшемся окне выбираем строки которые мы хотим выгрузить - только строки модели. Адрес сохранения перевода - общий словарь проекта. Отстуствующие переводы не заполнять.



После окончания выгрузки в папке src появится файл common_en.dict, представляющий собой пустой словарь примерно такого содержания (фрагмент)

Ключи=
Ключи\ поиска\ по\ которым\ необходимо\ искать\ данные,\ поиск\ работает\ по\ логическому\ "И"\.\n*\ Ключ\ -\ Строка\ -\ имя\ реквизита\ настройки\.=
Ключи\:=
Ключи\:\ Номенклатура\ (Ссылка),\ ИдентификаторыХарактеристик\ (Массив\ (Строка))=
КлючиВариантов=
КлючиВариантовОтчета=
КлючиВсехНастроек=
КлючиВыделенныхСтрок=
КлючиДляУдаления=
КлючиДоступа=
КлючиДоступа\.Список\ \=\ &=
КлючиДоступа\.Ссылка\ В\n\t\t\t\t(ВЫБРАТЬ\n\t\t\t\t\tШапка?\.Ссылка\n\t\t\t\tИЗ\n\t\t\t\t\tСправочник\.КлючиДоступа\ КАК\ Шапка?\n\t\t\t\tГДЕ\n\t\t\t\t\tШапка?\.Значение?\ В\ (&ВедущиеКлючиДоступа))=


Фильтруем полученный словарь следующим образом: убираем знак "=", удаляем строки, не содержащие кириллицу, удаляем строки с точками и пробелами. Строковыми литералами мы потом займёмся отдельно, сейчас наша задача - составить словарь для перевода идентификаторов.
Получаем словарь из 335 000 строк, после фильтрации 260 000

  • Далее берём перевод из файлов словарей в следующей последовательности:
    • 0_dict_uid.txt
    • 2_DictSB_NoDotsAndSpaces.txt
    • 4_SSL_auto.txt
    • 3_SSL_sloar_NoDotsAndSpaces.txt
  • Получаем объединённый словарь join_all.txt на 58 000 слов

Приведённый Bash-скрипт последовательно ищет переводы в каждом из перечисленных словарей, затем слова, для которых перевод не нашёлся, сохраняет в отдельный файл. Потом скрипт переводит этот файл по следующему словарю и так далее. В конце файлы переводов по каждому словарю объединяются в общий словарь Join_all.txt

sed -i 's/'='//' common_en.txt
grep -v '[\. ]' common_en.txt > common_en_clean.txt
grep -P '^.*?[а-яА-Я].*?$' 'common_en_clean.txt' > common_en_clean_ru.txt

join <(sort common_en_clean_ru.txt) <(sort -k1,1 0_dict_uid.txt) > join_uid.txt
join -v 1 <(sort common_en_clean_ru.txt) <(sort -k1,1 0_dict_uid.txt) > after_join_uid.txt

join <(sort -k1,1 after_join_uid.txt) <(sort -k1,1 2_DictSB_NoDotsAndSpaces.txt) > join_uid_dictSB.txt
join -v 1 <(sort -k1,1 after_join_uid.txt) <(sort -k1,1 2_DictSB_NoDotsAndSpaces.txt) > after_join_uid_dictSB.txt

join <(sort -k1,1 after_join_uid_dictSB.txt) <(sort -k1,1 4_SSL_auto.txt) > join_uid_dictSB_ssl_auto.txt
join -v 1 <(sort -k1,1 after_join_uid_dictSB.txt) <(sort -k1,1 4_SSL_auto.txt) > after_join_uid_dictSB_ssl_auto.txt

join <(sort -k1,1 after_join_uid_dictSB_ssl_auto.txt) <(sort -k1,1 3_SSL_sloar_NoDotsAndSpaces.txt) >
 join_uid_dictSB_ssl_auto_ssl_slovar.txt
join -v 1 <(sort -k1,1 after_join_uid_dictSB_ssl_auto.txt) <(sort -k1,1 3_SSL_sloar_NoDotsAndSpaces.txt) >
 after_join_uid_dictSB_ssl_auto_ssl_slovar.txt

cat join_uid.txt join_uid_dictSB.txt join_uid_dictSB_ssl_auto.txt join_uid_dictSB_ssl_auto_ssl_slovar.txt |
 awk '!seen[$0]++' > join_all.txt

 

3. Нормализация данных

Выполним обработку полученного словаря: почистим дубли слов (ключей) и переводов (значений).

Удалим из словаря неоднозначные переводы:

Загрузка Import
Загрузка Load
Запись Record
Запись Write
Запретить Deny
Запретить Disable

Скрипт для поиска дублей по первой колонке:

awk 'n=x[$1]{print n"\n"$0;} {x[$1]=$0;}' join_all.txt > join_all_duplicate_keys.txt # получил словарь дублей

Таких строк всего 300, можно почистить вручную.
Вручную почистил разные переводы каждого слова из файла join_all_duplicate_keys.txt, сохранил в файл join_all_duplicate_keys_removed.txt

Далее из файла join_all.txt удаляем все строки совпадающие по первой колонке с очищенным списком дублей join_all_duplicate_keys_removed.txt, затем добавляем этот очищенный список в низ словаря. Получаем словарь с уникальными ключами join_all_uniq_keys.txt

cat <(awk 'FNR==NR {f2[$1];next} !($1 in f2)' duplicate_keys_removed.txt join_all.txt) join_all_duplicate_keys_removed.txt 
   > join_all_uniq_keys.txt 

В полученном словаре удалим дубли переводов такого типа:

Другое Other
Прочие Other
Извещение Notification
Уведомление Notification
Заявление Statement
Ведомость Statement

Скрипт для поиска строк словаря с дублями переводов:

awk 'NR==FNR{s[$2]++;next} (s[$2]>1)' join_all_uniq_keys.txt join_all_uniq_keys.txt | sort -k2 >
 join_all_uniq_keys_duplicate_values.txt

В файле join_all_uniq_keys_duplicate_values.txt имеем 3700 строк с дублями.

Language Tool при наличии нескольких одинаковых переводов берёт только один из них. Т.е. в примере выше Заявление переведётся, а Ведомость останется без перевода. При этом плагин чувствителен к регистру, и если Ведомость перевести как STATEMENT, то переведутся оба слова и Заявление и Ведомость.

Потенциально проблемы могут вызывать одинаковые переводы в рамках общего контекста (будем называть их опасные дубли). Например две переменных в одном модуле, которые до перевода назывались по-разному, а после перевода - одинаково. Или два элемента на одной форме, или два реквизита одного справочника, и т.д. Такие слова надо перевести действительно по-разному, т.к. платформа не чувствительна к регистру: Statement и STATEMENT это один и тот же идентификатор.

Чтобы найти такие ситуации, проведём следующий анализ: проверим, какие слова из словаря дублей встречаются в одном и том же файле конфигурации (нпример в .bsl или .mdo файле).

Для выполнения этой проверки нам понадобится собрать словарь, в котором для каждого переводимого слова будет указан путь до объекта метаданных (до файла конфигурации) в котором это слово встречается. Выгрузим из конфигурации переводимые строки как было описано выше, но теперь поместим их не в общий словарь, а в контекстное хранилище переводов проекта. Режим заполнения переводов выберем - По исходному языку.

После этого в каждой папке в каталоге проекта появятся файлики *.trans, содержащие переводимые строки конкретной формы, модуля, шаблона и т.д. Соберём содержимое всех этих файлов вместе с путями до каждой строки в файл all_trans_w_path.txt с помощью скрипта: 

grep -Pr '--include=*.'trans '='  > '...\Translation\all_trans_w_path.txt'

Полученный файл представляет собой словарь в формате ПутьКФайлу:ПутьКПереводимойСтроке.ТипСтроки=ПереводимаяСтрока:

Catalogs/Банки/Forms/ФормаЭлемента/Module_en.trans:Изменить.Результат.Name=Результат
Documents/ЧекККМКоррекции/mdo_en.trans:Attribute.Кассир.Name=Кассир
Documents/СчетФактура/ManagerModule_en.trans:ИнициализироватьДанныеДокумента.String.ЭтоПродажа.Key=ЭтоПродажа
AccumulationRegisters/БонусныеБаллы/RecordSetModule_en.trans:ПриЗаписи.Запрос.Lines.БонуснаяКарта.Content=БонуснаяКарта
AccumulationRegisters/БонусныеБаллы/RecordSetModule_en.trans:ПриЗаписи.Запрос.Lines.Expr.НомерСтроки.Alias=НомерСтроки

Теперь "переведём" этот файл по нашему словарю дублей и проверим, где образовались одинаковые переводы внутри общего контекста.
Скрипт, с помощью которого был получен словарь опасных дублей (см. комментарии в коде):

# 1 Выбираем переводы только для нужных типов строк
# получили строки формата 'ПутьКФайлу:ПутьКПереводимойСтроке=ПереводимаяСтрока'
# 2 убираем ПутьКПереводимойСтроке (всё что между : и =)
# 3 убираем строки с рпобелами
# 4 к полученному списку добавляем перечень имён объектов метаданных из файла Configuration.mdo
# 5 оставляем строки с кириллицей
# 6 сортируем и оставляем только уникальные слова
cat \
<(grep -Pv '\.Lines=|\.Content=|\.Description=|\.TaskDescription=|\.Comment=|^Comment=|\.Condition=' all_trans_w_path.txt |\
   sed -E 's/:.*?=/=/' |\
   grep -v ' ') \
<(grep -Po '\..*?\<\/' Configuration.mdo | \
   sed 's/[\<\/]//g' | 
   sed 's/\./Configuration\.mdo=/') |\
 grep -P '=.*?[а-яА-Я]+' |\
 sort | uniq | sed 's/=/ /' \
 > trans_w_path_filtered.txt
# 6 сворачиваем предыдущий список, оставляя только уникальные сочетания путь+слово,
# 7 присоединяем переводы из файла join_all_uniq_keys_duplicate_values.txt: 
awk 'NR==FNR {file1[$1]=$0; next} $2 in file1 {print $1 " " file1[$2]}' join_all_uniq_keys_duplicate_values.txt
 <(awk '!a[$0]++' trans_w_path_filtered.txt) > used_duplicates_grouped.txt
# 8 оставляем строки, по которым есть одинаковые сочетания "путь - перевод"
# (для каждого пути остальись только уникальные ключи после предыдущей операции):
awk 'n=x[$1$3]{print n"\n"$0;} {x[$1$3]=$0;}' used_duplicates_grouped.txt > used_duplicates_grouped_filtered.txt 
# получили список вида "путь слово перевод"
# 9 убрали путь, оставили уникальные сочетания "слово перевод":
awk '!a[tolower($2$3)]++{print $2 " " $3}' used_duplicates_grouped_filtered.txt  | sort -k 2 >
 used_duplicates_grouped_filtered_uniq.txt

 

Полученный файл used_duplicates_grouped_filtered_uniq.txt является словарём из 900 опасных дублей, которым нужно вручную дать отличающиеся переводы. Результат работы я сохранил в файл used_duplicates_grouped_filtered_uniq_removed.txt

(На самом деле не все эти дубли являются опасными и список можно ещё сократить, но это требует более сложного анализа.)

Теперь с помощью уже использованного выше приёма внесём в словарь join_all_uniq_keys.txt изменения из файла used_duplicates_grouped_filtered_uniq_removed.txt:

cat <(awk 'FNR==NR {f2[$1];next} !($1 in f2)' used_duplicates_grouped_filtered_uniq_removed.txt join_all_uniq_keys.txt)
 used_duplicates_grouped_filtered_uniq_removed.txt > join_all_uniq_keys_uniq_values.txt

Оставшиеся в файле дубли считаем безопасными, т.е. после перевода конфигурации они не приводят к конфликтам внутри общего контекста. Для корректной работы плагина их достаточно разделить хотя бы по регистру.
Получим список дублей:

awk 'NR==FNR{s[$2]++;next} (s[$2]>1)' join_all_uniq_keys_uniq_values.txt join_all_uniq_keys_uniq_values.txt | sort -k2 >
 case_duplicates.txt

Как и ожидалось, у нас осталось 2700 дублей.
Для разделения дублей по регистру используем следующий подход:

  1. Составные лексемы из двух и более слов на примере ПолноеИмяРеквизита AttributeFullName
    • Для дубля приводим к верхнему регистру первое слово: ATTRIBUTEFullName
    • При наличии второго дубля приводим к верхнему регистру второе словао: AttributeFULLName
    • Для всех последующих дублей приводим к верхнему регистру начальные буквы: ATtributeFullName, ATTributeFullName и т.д.
  2. Одиночные слова на примере Active
    • Для каждого последующего дубля приводим к верхнему регистру ещё одну начальную букву: Active, ACtive, ACTive и т.д.

Скрипт, выполняющий данное преоброазование:

cat \
<(awk 'seen[$2]++ == 0' case_duplicates.txt) \
<(awk 'seen[$2]++ == 1' case_duplicates.txt \
| sed -r 's/( [A-Z]+)([A-Z][a-z].*$)/\L\1\E\2/' \
| sed -r 's/( [A-Z][a-z]+?)([A-Z].*)/\U\1\E\2/' \
| sed -r 's/( [A-Z][a-z])([a-z0-9]*$)/\U\1\E\2/') \
<(awk 'seen[$2]++ == 2' case_duplicates.txt |\
 sed -r 's/( [A-Z][a-z]+?)([A-Z][a-z]+)(.*)/\1\U\2\E\3/' |\
 sed -r 's/( [A-Z][a-z]{2})([a-z]*$)/\U\1\E\2/') \
<(awk 'seen[$2]++ == 3' case_duplicates.txt | sed -r 's/( [A-Z][a-z]{3})(.*$)/\U\1\E\2/') \
<(awk 'seen[$2]++ == 4' case_duplicates.txt | sed -r 's/( [A-Z][a-z]{4})(.*$)/\U\1\E\2/') \
<(awk 'seen[$2]++ == 5' case_duplicates.txt | sed -r 's/( [A-Z][a-z]{5})(.*$)/\U\1\E\2/') | \
sort -k2 > case_duplicates_removed_auto.txt

Это позволило автоматически обработать 2600 строк списка дублей, результат помещён в файл case_duplicates_removed_auto.txt
Оставшиеся 100 строк я обработал вручную и сохранил в файл case_duplicates_removed_manual.txt

Внесём изменения из этих двух файлов в наш словарь join_all_uniq_keys_uniq_values.txt:

cat <(awk 'FNR==NR {f2[$1];next} !($1 in f2)' case_duplicates_removed_auto.txt join_all_uniq_keys_uniq_values.txt)\
case_duplicates_removed_auto.txt > join_all_uniq_keys_uniq_values_case_sensitive.txt
cat <(awk 'FNR==NR {f2[$1];next} !($1 in f2)' case_duplicates_removed_manual.txt\
join_all_uniq_keys_uniq_values_case_sensitive.txt) case_duplicates_removed_manual.txt\
> join_all_uniq_keys_uniq_values_case_sensitive_final.txt

На этом закончено составление словаря идентификаторов.

4. Строковые литералы

Когда мы отфильтровали переводимые строки УНФ, убрав строки с пробелами и точками, размер словаря сократился с 335 000 до 260 000 тысяч строк. Что это за 75 000 строк, которые мы выкинули?

Это например описания процедур и функций: 

AccumulationRegisters/ПлатежныйКалендарь/RecordSetModule_en.trans:ПриЗаписи.Description=Процедура - обработчик события ПриЗаписи набора записей.

Комментарии объектов метаданных: 

AccumulationRegisters/СдельныеНаряды/mdo_en.trans:Resource.НормоЧасы.Comment=Загрузка в часах

Или просто встретившиеся в коде строки, которые плагин не смог распознать (типизировать). Среди них есть как "пользовательские" строки, которые не интересуют нас в рамках работы по переводу кода, так и "системные", котрые обязательно нужно перевести иначе получим неработоспособную конфигурацию.

Характерный пример - программная модификация текста запроса через функцию СтрЗаменить(). Скажем, такой код из модуля ВариантыОтчетов: 

	Запрос = Новый Запрос;
	ТекстЗапроса =
	"ВЫБРАТЬ
	|	ВариантыОтчетов.Ссылка КАК Ссылка
	|ИЗ
	|	Справочник.ВариантыОтчетов КАК ВариантыОтчетов
	|ГДЕ
	|	НЕ ВариантыОтчетов.ПометкаУдаления
	|	И ВариантыОтчетов.ТипОтчета = &ТипОтчета
	|	И ЕСТЬNULL(ВариантыОтчетов.Отчет.ПометкаУдаления, ИСТИНА)";
	
	ИмяТаблицы = "Справочник.ВариантыОтчетов";
	Если Режим = "ОбщиеДанныеКонфигурации" Тогда
		ТекстЗапроса = СтрЗаменить(ТекстЗапроса, ".ВариантыОтчетов", ".ПредопределенныеВариантыОтчетов");
		ТекстЗапроса = СтрЗаменить(ТекстЗапроса, "И ВариантыОтчетов.ТипОтчета = &ТипОтчета", "");
		ИмяТаблицы = "Справочник.ПредопределенныеВариантыОтчетов";
	КонецЕсли;
	
	Запрос.Текст = ТекстЗапроса;
	СсылкиУдаляемыхВариантов = Запрос.Выполнить().Выгрузить().ВыгрузитьКолонку("Ссылка");

Плагин переведёт весь код и текст запроса, но он не знает как интерпретировать строку "И ВариантыОтчетов.ТипОтчета = &ТипОтчета". Поэтому вся строка целиком пойдёт в словарь и для неё нужно задать отдельный перевод, не смотря на то что в словаре уже есть перевод по отдельности для "ВариантыОтчетов" и "ТипОтчета".

Чтобы не переводить одно и то же несколько раз, воспользуемся следующим приёмом: выделим из файла all_trans_w_path.txt интересующие нас строковые литералы, а затем заменим все слова на их перевод из подготовленного уже словаря идентификаторов.

Составление словаря строк: 

grep -P '\.Lines=' all_trans_w_path.txt |\
 sed -r 's/^.*?\.String\.(.*?)\.Lines=/\1~/' |\
# в контекстном словаре ключ сохраняется с символами пробела, табуляции и переноса строки в начале и конце строки,
# а в общем словаре они обрезаются; удаляем эти символы чтобы преобразовать формат от контекстного словаря к общему:
 sed -r 's/^(\\\ |\\t|\\n)*// ; s/(\\\ |\\t|\\n)*~/~/' |\
 awk -F'~' '!seen[$2]++' > tmp/trans_w_path_lines.txt

Перевод словаря строк по словарю идентификаторов: 

sed -r 's/(^.*?) (.*)/s\/\\b(\[nt\]\?)\1\\b\/\\1\2\/g/' join_all_uniq_keys_uniq_values_case_sensitive_final.txt > common_en_script.txt
sed -rf common_en_script.txt <(cut -d~ -f2 trans_w_path_lines.txt) > trans_w_path_lines_values_trans.txt
paste -d' ' <(cut -d~ -f1 trans_w_path_lines.txt) trans_w_path_lines_values_trans.txt > trans_w_path_lines_translated.txt

Всё готово! Объединяем словарь идентификаторов и словарь строк, вносим небольшие правки и формируем итоговый файл словаря common_en.dict: заменяем разделитель (пробел) на знак '=', добавляем необходимую шапку файла и приводим окончания строк к формату Windows: 

cat tmp/join_all_uniq_keys_uniq_values_case_sensitive_final.txt tmp/trans_w_path_lines_translated.txt |\
 LC_COLLATE=C.UTF-8 sort -k1b,1 |\
 sed -r 's/([^\\]) /\1=/' | sed '1i#Translations for: common' |\
 perl -p -e 's/\n/\r\n/'\
 > common_en.dict

4. Анализ полученного словаря

Общее количество строк в словаре идентификаторов УНФ 1.6 260 000 шт.
В нашем словаре идентификаторов 58 000 слов, что составляет 22% от общего количества.

Чтобы получить процент перевода кода и модели конфигурации, подсчитаем долю по количеству мест использований слов.
Общее количество использований переводимых строк в УНФ 1.6 512 000 шт.
Из них по нашему словарю переводится 295 000 мест использования.

Можно оценить, что доля перевода исходного кода конфигурации примерно равна 58%

Из конфигурации удалены наиболее объёмные по тексту объекты российской специфики - регламентированные отчёты, обработки ЭДО, классификаторы типа ВЕТИС и пр.

5. Полезные команды

  • Вывод дублей по колонке 1 ($2 - по второй, можно по сочетанию колонок, например $1$3 - первая и третья)
    awk 'n=x[$1]{print n"\n"$0;} {x[$1]=$0;}' file
    На практике этот способ хорошо сработал при поиске дублей по первой колонке, но при поиске дублей по второй колонке часть строк вывода задваивалась. Поэтому я использовал...
  • Альтернативный способ поиска дублей по колонке:
    awk 'NR==FNR{s[$2]++;next} (s[$2]>1)' file file
  • Удаление строк с дублями по колонке (сочетанию колонок). Остаются только строки с уникальным значением ключа.
    Вывод строк с уникальными значениями колонок номер 2 и 3. Остальные колонки отбрасываются:
    awk '!a[$2$3]++{print $2 " " $3}' file
    Вывод строк с уникальными значениями колонок номер 2 и 3. Выводится вся строка (все колонки):
    awk '!a[$2$3]++' file
  • Соединение файлов по ключевой колонке (или сочетанию колонок):
    awk 'NR==FNR {f1[$1]=$0; next} {print $1 " " f1[$2]}' file1 file2
    В отличие от команды join, не требуется сортировка файлов. Это важно когда хочется сохранить порядок строк после мёрджа.
  • Вывод всех строк файла2, для которых нет соответствия в файле1 по заданному ключу:
    awk 'FNR==NR {f2[$1];next} !($1 in f2)' file1 file2

6. Дальнейшие планы

С помощью предложенных в статье приёмов можно на основании имеющихся словарей собрать и нормализовать словарь для перевода конфигурации. В моём примере существующих ресурсов хватило на перевод 58% исходного кода. Чтобы увеличить процент и продвинуться в переводе дальше - необходимо создание новых словарей. Сейчас это в основном решается силами переводчиков, т.к. качество машинного перевода идентификаторов оставляет желать лучшего, и в конечном итоге словарь составляется/редактируется человеком. В следующей статье мы посмотрим, как можно улучшить качество машинного перевода, чтобы минимизировать участие человека.

7. Приложения

В архиве DemoBuild.zip вы можете найти демо-версии всех использованных словарей и скрипт выполняющий сборку итогового словаря по описанному в статье алгоритму. Нужно распаковать архив и запустить compile_common_en.sh - будет создан файл словаря common_en.dict

Скачать файлы

Наименование Файл Версия Размер
DemoBuild.zip

.zip 6,04Mb
05.04.20
0
.zip 6,04Mb Скачать

Специальные предложения

Оставьте свое сообщение

См. также

Работа со схемой запроса Промо

Инструментарий разработчика Практика программирования v8 v8::Запросы Абонемент ($m)

Стандартом взаимодействия с реляционной базой данных стал язык SQL. Приемником SQL в 1С является язык запросов. Язык запросов, также как и SQL, является структурированным. Составляющие структуры запроса отвечают на разные вопросы о том, какие данные требуется получить и какие манипуляции с множествами данных необходимо произвести при получении. В простых случаях текст запроса можно написать вручную, однако в сложных случаях, а также при программном формировании, - лучше воспользоваться объектной моделью запроса и использовать объект "Схема запроса". В статье дается описание объектной модели и особенностей работы с ней, а также приводится решение, упрощающее взаимодействие с объектом "Схема запроса".

1 стартмани

24.04.2018    43627    kalyaka    35    

Библиотека программного изменения формы (УФ)

Инструментарий разработчика Работа с интерфейсом Универсальные функции v8 1cv8.cf Абонемент ($m)

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

1 стартмани

07.08.2020    3823    BuriyLesha    17    

Перевод кода и метаданных конфигурации на английский язык с помощью плагина EDT: Language Tool

EDT Локализация решений v8 1cv8.cf Абонемент ($m)

Использование регулярных выражений для парсинга .mdo-файлов и составления русско-английского словаря метаданных. Перевод кода и метаданных конфигурации по словарю с помощью нового инструмента 1С - плагина EDT: Language Tool на примере УНФ 1.6

1 стартмани

03.04.2020    2004    vanjushkin    10    

1С и PowerShell - обновление из хранилища

Администрирование данных 1С Инструментарий разработчика v8 Абонемент ($m)

Пример скрипта, упрощающего работу.

1 стартмани

29.08.2019    8498    Jokemas    25    

Hello world на metadata.js Промо

Инструментарий разработчика WEB Мобильная разработка v8 1cv8.cf Абонемент ($m)

Про браузерные offline-first приложения можно написать миллионы слов. Сэкономлю своё и ваше время и перейду сразу к делу. В статье не будет рекламы и агитации за новые технологии, не будет критики традиционных или попсовых решений. Рассмотрим по шагам разработку простейшей программы на metadata.js. Постараюсь сделать акцент не на том «как это сделано», а «почему сделано именно так»

1 стартмани

11.08.2016    58028    unpete    208    

Менеджер потоков: реализация "любой" задачи в потоках

Производительность и оптимизация (HighLoad) Инструментарий разработчика v8 Абонемент ($m)

Менеджер потоков – один их новых инструментов, который упрощает работу разработчиков. Насколько легко с ним, на конференции Infostart Event 2018 Education показал начальник отдела автоматизации 1С Иван Филимонов компании «Трансстроймеханизация».

01.08.2019    9444    DarkAn    6    

Использование фреймворка "Тестирование 3.0" (https://testingtool.ru) для тестирования веб-приложений

Инструментарий разработчика v8 Абонемент ($m)

Рассматривается использование фреймворка "Тестирование 3.0" (https://testingtool.ru) для тестирования веб-приложений.

1 стартмани

24.12.2018    5046    AlexKo    9    

Go. Разбор лога технологического журнала. Достойная альтернатива perl'у

Сервисные утилиты Инструментарий разработчика v8 1cv8.cf Абонемент ($m)

Началось все с того, что я познакомился с перловыми скриптами для парса ТЖ которые размещены на kb.1c.ru (например в этой статье https://kb.1c.ru/articleView.jsp?id=113). По началу мне дико понравилось то, что перл разбирал гигабайты логов за считанные минуты, но позитив мой угасал обратно пропорционально с тем, насколько глубже я погружался в "кроличью нору" ....

1 стартмани

24.10.2018    20009    lazarenko    39    

HTTP Сервисы: Путь к своему сервису. Часть 4

Инструментарий разработчика Практика программирования v8 1cv8.cf Абонемент ($m)

Продолжение статьи «HTTP Сервисы: Путь к своему сервису. Часть 3». В предыдущих частях мы уже о многом поговорили. В этой части поговорим про размер сообщений, о файлах, о порциях и немножко, о регламентах.

1 стартмани

28.09.2018    24352    dsdred    15    

HTTP Сервисы: Путь к своему сервису. Часть 2

Инструментарий разработчика Практика программирования v8 1cv8.cf ERP2 УТ11 КА2 Абонемент ($m)

Продолжение статьи «HTTP Сервисы: Путь к своему сервису. Часть 1». В этой части будет "Микс" из OData+HTTP-Сервис(Get)+СКД. Наш пример будет работать как в браузере, так и в написанной нами обработке. Работать будем с разными версиями платформ.

1 стартмани

13.08.2018    32539    dsdred    0    

Тестирование: пример создания сценарного UI теста для платформы 1С

Инструментарий разработчика v8 ERP2 УТ11 Абонемент ($m)

В этой статье мы расскажем, как создать сценарный UI-тест. Опишем последовательность действий и покажем, как это сделать с использованием инструментария. Рассмотрим пример, максимально приближенный к боевому, покажем на примере конфигураций УТ11/ERP проверку бизнес-процесса "Продажа". Вы сможете убедиться, что создание сценарных тестов для платформы 1С на самом деле относительно быстрый и простой процесс.

1 стартмани

17.04.2018    20319    ivanov660    11    

Консоль запросов со встроенным Конструктором запросов для 1с8.3 (8.2) своими руками

Консоль запросов v8 v8::УФ v8::Запросы 1cv8.cf Абонемент ($m)

Мы можем сами создать свою консоль запросов - именно такую, которая подходит для наших нужд. Кроме того, создав собственную Консоль запросов, Вы не только получаете удобный для себя инструмент, а также получаете навык программирования в среде 1с8, что очень полезно будет начинающим программистам 1С.

1 стартмани

21.12.2017    21339    jan-pechka    23    

Полезный код для программистов 1С (часть 1). Управление свойствами элементов формы. Хранение копии данных реквизитов

Инструментарий разработчика Практика программирования v8 Абонемент ($m)

У каждого программиста за время работы накапливается полезный инструментарий, которым он привык пользоваться. Естественно и у меня он тоже имеется. И вот решено было немного поделиться с сообществом. Возможно идеи не новые. Более того, допускаю, что реализованы они не самым оптимальным образом. Но ведь для этого сообщество и существует, чтобы делиться с ним, получая обратную связь.

1 стартмани

24.09.2017    42055    vandalsvq    80    

Интеграция сценарного тестирования в процесс разработки

Практика программирования Инструментарий разработчика v8::УФ Абонемент ($m)

Эта статья является практическим пособием по внедрению тестирования на основе сценариев в процесс разработки программного обеспечения на базе платформы 1С:Предприятие 8.3. Документ отличает прикладная направленность, в нем содержится много кода, подходов и конкретики. Все рассмотренные примеры основаны на использовании бесплатной конфигурации Тестер

1 стартмани

04.07.2017    29933    grumagargler    30    

Перехват методов серверных (x64) контекстов с использованием DynamicWrapperX

Инструментарий разработчика v8 Абонемент ($m)

Применение COM-объекта DynamicWrapperX на x64-сервере приложений.

1 стартмани

23.03.2017    11719    chessman    7    

Как сделать простой парсер сложных запросов

Инструментарий разработчика Практика программирования v8 1cv8.cf Абонемент ($m)

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

1 стартмани

11.07.2013    8620    blockcode    8    

Подсветка синтаксиса 1C (в том числе языка запросов) в Notepad++

Инструментарий разработчика v8 1cv8.cf Россия Абонемент ($m)

Конфигуратор 1С как редактор кода не всегда удовлетворяет потребностям программиста в управлении кода. Я зачастую с завистью вспоминаю другие среды разработки программ, и нередко копировал куски 1С кода в стороннюю программу для каких-либо манипуляций - например, Notepad++. К сожалению, в нём нет встроенной поддержки синтаксиса кода 1С, из-за чего пришлось определять свой. Вот об этом я и расскажу.

1 стартмани

27.03.2012    34865    CratosX    33    

Текстовые экспандеры - в помощь программисту 1С

Инструментарий разработчика v8 1cv8.cf Россия Абонемент ($m)

Каждый человек старается по возможности облегчить себе труд. Программисты не исключение. Каждый день мы сталкиваемся с необходимостью писать однотипные фрагменты программного кода. Для автоматизации этого процесса система 1С:Предприятие позволяет использовать шаблоны текста (как стандартные, так и созданные пользователем). Казалось бы, что еще нужно разработчику? Однако, в некоторых случаях, стандартных средств разработки все-таки бывает недостаточно. Например, разрабатывая правила обмена в конфигурации 1С:Конвертация данных, приходится писать довольно большие тексты, не имея при этом возможности воспользоваться ни автоподстановкой, ни шаблонами. Либо, приходя к очередному клиенту, Вы обнаруживаете, что нужно написать, допустим, самую обычную печатную форму, которую Вы писали тысячу раз, но процесс ее создания может занять продолжительное время. Как раз в этом случае и могут помочь программы для вставки часто используемых выражений – текстовые экспандеры.

1 стартмани

27.07.2011    25922    tomvlad    44