6

Как можно преобразовать строку расширения имени файла (например, png) в универсальный идентификатор типа (например, public.png)?

Я ищу скрипт общего назначения или утилиту, а не что-то вроде mdls -name kMDItemContentTypeTree <file> .

4 ответа4

5

Самый простой способ сделать это - использовать UTTypeCreatePreferredIdentifierForTag():

#import <Foundation/Foundation.h>

int main (int argc, const char * argv[]) {
    NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init];
    NSArray *args = [[NSProcessInfo processInfo] arguments];

    if ([args count] < 2) {
        printf("usage:\n");
        printf("uti <filenameExtension>\n");
        exit(EXIT_SUCCESS);
    }

    NSArray *extensions = [args
                 subarrayWithRange:NSMakeRange(1, [args count] - 1)];

    for (NSString *filenameExtension in extensions) {
        NSString *utiType = (NSString *)UTTypeCreatePreferredIdentifierForTag(
                              kUTTagClassFilenameExtension,
                           (CFStringRef)filenameExtension, NULL);

        printf("%s\n", [utiType UTF8String]);
        [(NSString *)utiType release];
    }

    [pool drain];
    return 0;
}

Скомпилированный исполняемый файл uti и исходный код: uti.zip

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

MacPro:~ mdouma46$ /Users/mdouma46/Developer/uti/uti png tga mov sdfad
public.png
com.truevision.tga-image
com.apple.quicktime-movie
dyn.age81g3dgqfwa

("неизвестные" расширения файлов сопоставляются с UTI, которые начинаются с префикса dyn. ).

3

В случае, если речь идет в первую очередь об удобстве (хотя я хочу удалить):

#!/usr/bin/env bash

if [ $# = 0 ] ; then
        echo "Fail param"
        exit 1
fi

ext=$1
export TMPDIR=$HOME/Library
t=$( mktemp -t getuti.XXXXXX )

if [ $? != 0 ] ; then
        echo "Fail mktemp"
        exit 1
fi

mv $t $t.$ext

if [ $? != 0 ] ; then
        echo "Fail mv"
        exit 1
fi

while true ;
do
        uti=$( mdls -name kMDItemContentTypeTree -raw -nullMarker $t $t.$ext )
        if [ "$uti" = "${uti//$t/}" ] ; then
                echo "$uti"
                rm -f $t.$ext
                exit 0
        fi
        sleep 1
done

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

$ ./getuti.sh jpeg
(
    "public.jpeg",
    "public.image",
    "public.data",
    "public.item",
    "public.content"
)
$ ./getuti.sh gif
(
    "com.compuserve.gif",
    "public.image",
    "public.data",
    "public.item",
    "public.content"
)
$ ./getuti.sh mdown
(
    "net.daringfireball.markdown",
    "public.text",
    "public.data",
    "public.item",
    "public.content"
)
$ ./getuti.sh foobarbazqux
(
    "public.data",
    "public.item"
)
2

getuti

if [[ $# == 0 ]]; then
    echo "Usage: getuti extension ..."
    exit 1
fi
for x in $@; do
    f="/tmp/me.lri.getuti.$x"
    touch "$f"
    mdimport "$f"
    mdls -name kMDItemContentType "$f" | sed 's|.*"\(.*\)"|\1|'
    rm "$f"
done

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

$ getuti png pngooo
public.png
dyn.ah62d4rv4ge81a5xhr7108
0

Начиная с версии 1.5.2, duti (установка через Homebrew: brew install duti) поддерживает параметр -e недокументированный с 1.5.2), который извлекает объявление UTI, связанное с указанным расширением имени файла:

duti -e .png

выходы, например:

identifier: public.png
description: Portable Network Graphics image
declaration: {
    UTTypeIdentifier = public.png
    UTTypeDescription = Portable Network Graphics image
    UTTypeConformsTo = public.image
    UTTypeTagSpecification = {
        com.apple.ostype = PNGf
        public.mime-type = image/png
        com.apple.nspboard-type = Apple PNG pasteboard type
        public.filename-extension = png
    }
}

Таким образом, чтобы получить только UTI для расширения .png , используйте:

duti -e .png | awk '{ print $2; exit }' # -> 'public.png'

Всё ещё ищете ответ? Посмотрите другие вопросы с метками .