Ищем команду терминала для разбора файла данных словаря MacOSX

Проблема

MacOSX поставляется со словарями, хранящимися в /Library/Dictionaries. Я хотел бы проанализировать их, чтобы программно получить результаты словаря (через терминал, AppleScript или Automator). Словари представляют собой пакеты MacOSX, и все они имеют папку Contents, содержащую файл с именем Body.data. Я хотел бы проанализировать этот файл для строки UTF-8 (возможно, двойные байты китайского символа) и вернуть строки, в которых найдена строка.

Я пробовал следующее, которое не возвращает никаких результатов:

find . -name 'Body.data' -exec grep -li '我' {} \;

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

Обновить

Следующее сработало для меня на основе принятого ответа:

Создал и заархивировал утилиту командной строки под названием rdef, используя Xcode с этим кодом:

#import <Foundation/Foundation.h>

int main(int argc, const char * argv[])
{

    @autoreleasepool {

        if(argc < 2)
        {
            printf("Usage: rdef <word to define>");

            return -1;
        }

        NSString * search =
        [NSString stringWithCString: argv[1] encoding: NSUTF8StringEncoding];

        CFStringRef def =
        DCSCopyTextDefinition(NULL,
                              (__bridge CFStringRef)search,
                              CFRangeMake(0, [search length]));

        NSString * output =
        [NSString stringWithFormat: @"Definition of <%@>: %@", search, (__bridge NSString *)def];

        printf("%s", [output UTF8String]);


    }
    return 0;
}

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

frameworks-added

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

Для развертывания:

Щелкните правой кнопкой мыши архивный пакет и выберите «Показать в Finder». Затем отобразите содержимое пакета, разверните папку продукта и скопируйте исполняемый файл в /local/usr/bin. Теперь из командной строки я могу запустить утилиту следующим образом:

rdef 我|awk -F '\|' '{ gsub(/^ +| +$/, "", $2); print $2 }'

Пожалуйста, смотрите принятый ответ ниже для расширенных ссылок.

Примечание: github для утилиты можно найти по адресу https://github.com/mingsai/rdef.git

Далее я просто создам службу для вызова утилиты из Automator для выделенного текста.

Сервисное решение

Чтобы заплатить тем, кто помог, особенно @mklement0: вот решение для использования командной утилиты и преобразования ее в службу MacOSX, которую можно использовать для перевода китайских иероглифов в пиньинь.

Создайте новый файл службы Automator и убедитесь, что выбранный вывод заменяет выделенный текст.

Служба MacOSX — преобразование китайского языка в пиньинь

Подробнее о скрипте Automator

PATH=/bin:/usr/bin:/sbin:/usr/sbin:/usr/local/bin/: 
export PATH
LC_CTYPE=UTF-8
x=$1

for ((i=0;i<${#x};i++)); do rdef "${x:i:1}" | awk -F  '\|' 'BEGIN {ORS=" "}{ gsub(/^ | +?/, "", $2); if (length($2) > 0) print $2 ; exit}'; done

Чтобы сделать службу «живой», просто удалите «Запросить текст» и сохраните службу с именем по вашему выбору (например, «Преобразовать в пиньинь»).

Чтобы использовать обновленную службу, выделите все китайские символы и щелкните правой кнопкой мыши контекстное меню, затем в нижней части меню «Службы» выберите «Преобразовать в пиньинь» ... (как указано ниже)

Использование

выделенный текст

Service-Selection

Производит этот вывод

выход

Надеюсь, что это поможет любому с этой проблемой.


person Tommie C.    schedule 22.03.2014    source источник
comment
Спасибо за обновление; С тех пор мне удалось упростить команду awk, см. мой обновленный ответ. Если вы готовы к этому, было бы здорово, если бы вы также добавили особенности того, как вы настраиваете проект Xcode (какие фреймворки, включает,...).   -  person mklement0    schedule 22.03.2014
comment
@ mklement0 - упрощенная версия awk улавливала случайный символ вертикальной черты. Я обновил вопрос с помощью добавленной мной структуры. Это и код, заменяющий функцию main, — это все, что нужно для того, чтобы команда rdef заработала.   -  person Tommie C.    schedule 22.03.2014
comment
Спасибо за обновление. Второй __bridge в вашем коде, вероятно, должен быть __bridge_transfer, чтобы ARC взял на себя ответственность и освободил для вас строку def (в качестве альтернативы, в конце, вызовите CFRelease(def)). Насчет приблудой трубы: странно; возможно awk -F ' *[|] *' '{ print $2 }' сработает.   -  person mklement0    schedule 23.03.2014
comment
@ mklement0 Спасибо, что указали на проблему с выпуском. У меня есть небольшое уточнение, о котором я хотел бы попросить, если у вас есть свободная минутка. В некоторых случаях у меня есть выходные данные, которые производят два набора совпадений: например, rdef 都 производит -Definition of ‹都›: | доу | все, оба целиком (из-за) каждый даже уже | ду | столица метрополия фамилия Ду и я хотел бы просто взять только первые подходящие трубы. Любые мысли?ТИА   -  person Tommie C.    schedule 24.03.2014
comment
Если вы получаете две выходные строки и хотите обработать только первую, все, что вам нужно сделать, это добавить ; exit после print $2 в программе awk. Каким словарем вы пользуетесь? Ближе всего к моей машине подходит Оксфордский китайский словарь (упрощенный китайско-английский), но он не дает такого же результата.   -  person mklement0    schedule 24.03.2014
comment
@mklement0 - у меня около 6 китайских словарей. Этот последний комментарий исправил это! Я обязательно поделюсь настройкой службы в своем решении. Я пытался сгруппировать () и {1} безрезультатно.   -  person Tommie C.    schedule 24.03.2014
comment
Благодарим вас за публикацию сведений об услуге Automator. Что касается самого rdef: обратите внимание, что вы создали универсальную утилиту, которая выполняет поиск во всех словарях, которые пользователь выбрал в диалоговом окне «Настройки» Dictionary.app. И наоборот, это означает, что он будет работать с китайским вводом только в том случае, если выбран китайский словарь; Я предлагаю вам обновить описание на github. (Кстати: что означает r в rdef?)   -  person mklement0    schedule 24.03.2014
comment
@ mklement0 - еще раз взгляну на описание на github. r просто произвольно, я уверен, что в конечном итоге это будет означать что-то остроумное ;-)   -  person Tommie C.    schedule 24.03.2014


Ответы (2)


grep работает с текстовыми файлами, но файлы Body.data, к сожалению, не являются текстовыми файлами.

Лучше всего, вероятно, создать собственную утилиту командной строки в Xcode, как предлагается здесь (пример кода): https://discussions.apple.com/thread/2679911

Вот документация API словаря Apple: https://developer.apple.com/library/mac/documentation/UserExperience/Conceptual/DictionaryServicesProgGuide/access/access.html#//apple_ref/doc/uid/TP40006152-CH5-SW1

Обновление:

Предполагая, что вы создали утилиту с именем rdef, которая возвращает что-то вроде 'Definition of <我>: | wǒ | I me my', используйте следующую команду awk для разбора пиньинь:

rdef "我" | awk -F ' *[|] *' '{ print $2 }'

В качестве альтернативы, если вам подходит онлайн-решение, вы можете попробовать решение на основе Google Translate.

По крайней мере, при интерактивном использовании вы получаете транскрипцию пиньинь под полем ввода.

Например, ваш примерный символ транскрибируется как «Wǒ»:

http://translate.google.com/?text=%E6%88%91#zh-CN/en/%E6%88%91

person mklement0    schedule 22.03.2014
comment
Создание утилиты командной строки работает хорошо, теперь мне просто нужно немного проанализировать вывод на основе шаблонов, возвращаемых из словаря. Например: rdef 我 возвращает: Определение ‹我›: | wǒ | У меня есть свои мысли о том, как разобрать только пиньинь внутри каналов из терминала для достижения моей первоначальной цели. Как вы упомянули, grep работает с файлами. - person Tommie C.; 22.03.2014
comment
@TommieC.: С удовольствием; вам просто нужно передать команду поиска в awk — см. мой обновленный пример. - person mklement0; 22.03.2014

Я просмотрел файлы Chinese Simplified и Oxford English Dictionary, и у обоих есть файлы Contents и Body.data, как вы говорите. Однако, если я бегу

file Body.data

он просто говорит data (а не ASCII текст или UTF-8) - это означает, что файл двоичный, а не ASCII, поэтому grep и его друзья вообще не будут работать с ними очень хорошо.

На случай, если кто-то сможет определить тип файла из шестнадцатеричного дампа, файлы начинаются так:

0000000      0000    0000    0000    0000    0000    0000    0000    0000
          \0  \0  \0  \0  \0  \0  \0  \0  \0  \0  \0  \0  \0  \0  \0  \0
*
0000100      c9a8    0106    0000    0000    ffff    ffff    0020    0000
         250 311 006 001  \0  \0  \0  \0 377 377 377 377      \0  \0  \0
0000120      0000    0000    0207    0000    ffff    ffff    ffff    ffff
          \0  \0  \0  \0  \a 002  \0  \0 377 377 377 377 377 377 377 377
0000140      8009    0000    8005    0000    8c22    0004    9c78    bddc
          \t 200  \0  \0 005 200  \0  \0   " 214 004  \0   x 234   ܽ  **
0000160      6c6b    db1b    2f7e    e416    49a6    349a    c5b8    902d
           k   l 033 333   ~   / 026 344 246   I 232   4 270 305   - 220
0000200      fda2    7134    7880    d4ef    2cb6    96d9    9dad    f673
person Mark Setchell    schedule 22.03.2014
comment
Большое спасибо за понимание. Я создал утилиту командной строки для решения половины проблемы, но проголосовал за ваш ответ, потому что он очень полезен. - person Tommie C.; 22.03.2014