Как редактировать метаданные файлов в OS X?

кто-нибудь знает, можно ли напрямую редактировать метаданные файлов в OS X. конкретно в perl. Параметр, который я специально пытаюсь изменить, -kMDItemFSLabel (цвет файл). У меня был поиск, и я не могу найти способ сделать это без использования модуля, такого как Mac:: Клей или внешнее приложение (Finder).

3 ответов


на kMDItemFSLabel атрибут является свойством Finder. Вам нужно использовать способ связи с Finder для изменения его данных. Насколько я знаю, нет бит, который вы можете крутить с Perl, чтобы изменить данные Finder, не проходя через Finder.

есть несколько способов сделать это:

  1. использовать CamelBones когда выйдет новая версия. Это позволяет мосту к цели C от Perl. Тогда вам нужно будет использовать Apple метод с системными вызовами Cocoa. Крутая кривая обучения для какао...

  2. если у вас есть инструменты разработчика, используйте /Developer / Tools / SetFile (если это поддерживает элемент метаданных)

  3. используйте osascript для отправки сообщения в Finder для изменения цвета файла. Вы можете посмотреть этой ранее так сообщение для намеков на это.

большинство мостов Perl, связанных с целью C / Cocoa, умерли к сожалению. MacPerl не обновлялся с 2005 года.

почти все самые простые методы требуют знания хотя бы минимального количества Applescript и вызова текста этого скрипта, хотя интерполированный вызов типа osascript.

в своей форме 1 строки osascript делает Perl красивым:

osascript -e 'tell application "Finder"' -e "activate" -e "display dialog \"hello\"" -e 'end tell'

чтобы использовать osascript из Perl, большинство использует здесь документ. Есть примеры из книги, которую я назвал Applescript-The Окончательное Руководство и brian d foy на управление iTunes с Perl.

вот скрипт в Perl, который я написал для настройки цвета файла с помощью osascript:

#!/usr/bin/perl
use strict; use warnings;
use File::Spec;
use String::ShellQuote; 

sub osahere  { 
    my $rtr;
    my $scr='osascript -ss -e '."'".join ('',@_)."'";
    open my $fh, '-|', $scr or die "death on osascript $!";
    $rtr=do { local $/; <$fh> };
    close $fh or die "death on osascript $!";
    return $rtr;
}

sub set_file_color {
# -- No color = 0
# -- Orange = 1
# -- Red = 2
# -- Yellow = 3
# -- Blue = 4
# -- Purple = 5
# -- Green = 6
# -- Gray = 7

my $file=shift;
my $color=shift || 0;
$color=0 if $color<0;
$color=7 if $color>7;

$file=File::Spec->rel2abs($file) 
    unless File::Spec->file_name_is_absolute( $file );
$file=shell_quote($file);

return undef unless -e $file;

my $rtr=osahere <<"END_SET_COLOR" ;
tell application "Finder"
    set f to "$file"
    set ItemToLabel to POSIX file f as alias
    set the label index of ItemToLabel to $color
end tell
END_SET_COLOR

return $rtr;
}

set_file_color("2591.txt",2);

если цвет искателя равен 0,kMDItemFSLabel равен 0. Если есть какой-либо набор цветов, kMDItemFSLabel становится 8-цвет. т. е. ярлык "оранжевый" - это label index 1, kMDItemFSLabel = 7; ярлык "красный"label index 2, kMDItemFSLabel = 6; и так далее.


в Perl нет встроенной функции для работы с метаданными файловой системы Mac. Либо вы используете библиотеку из CPAN, либо пишете ее сами, вероятно, не так хорошо, как автор той, что была в CPAN.


на самом деле это не так сложно реализовать. Вы можете использовать xattr команда, как показано в строке ниже док... Я завернул основную функцию в скрипт python, который применяет именованные цвета к ряду файлов...

#!/usr/bin/env python

"""
==================================
LABELCOLOR.PY - Colorize Finder labels of files

Usage:
  labelcolor.py [color] *.jpg

  where color is a name or abbreviation as defined below:
    clear (c), gray (a), green (g), purple (p), 
    blue (b), yellow (y), red (r), orange (o)

The shell command used is:
  xattr -wx com.apple.FinderInfo \
  0000000000000000000400000000000000000000000000000000000000000000 myfile.txt
where 04 in the middle of the zeroes is the color definition
==================================
"""
import sys
import os
import subprocess

def colorizeFile(ColorName,FileName):
    ReverseTable = {
         "clear"  :  "01",
         "gray"   :  "03",
         "green"  :  "04",
         "purple" :  "06",
         "blue"   :  "09",
         "yellow" :  "0A",
         "red"    :  "0C",
         "orange" :  "0E",
         "c"      :  "01",
         "a"      :  "03",
         "g"      :  "04",
         "p"      :  "06",
         "b"      :  "09",
         "y"      :  "0A",
         "r"      :  "0C",
         "o"      :  "0E",
    }

    HexString = 18*"0" + ReverseTable.get(ColorName) + 44*"0"
    Xcommand = 'xattr -wx com.apple.FinderInfo {0} {1}'.format(HexString,FileName)
    ProcString = subprocess.check_call(Xcommand, stderr=subprocess.STDOUT,shell=True) 

if __name__ == "__main__":
    if len(sys.argv)<3:
        sys.stderr.write(__doc__.format(sys.argv[0]))
    else:
        Cname = sys.argv[1]
        Flist = sys.argv[2:]
        for File in Flist:
            colorizeFile(Cname.lower(),File)
        sys.stderr.write("## Colorized {0} file(s) as {1}\n".format(len(Flist),Cname))