Как добавить OS X "теги" в файлы программным способом?
начиная с Mavericks, OS X имеет возможность помечать и окрашивать файлы в Finder.
есть ли способ добавить теги в файлы через API Cocoa или с помощью команды оболочки?
10 ответов
извините за добавление другого ответа, но тот, который связан с настройкой цветов метки, уже был довольно длинным. Вот выдержка из скрипта python, который я использую для установки пользовательских тегов. Кажется, что это работает, чтобы сделать вещи доступными для поиска, но не уверен, что теги будут отображаться правильно. Использование в основном:
tagfile.py "Tag Name" FileOrFolderName
код ниже.
#! /usr/bin/env python
# -*- coding: utf-8 -*-
""" Write tags to file
Usage:
tagfile.py "TagName" FileName1 FileName2
You can use wildcards for the file name. Use quotes if spaces in tags.
To check if it worked, use xattr -l FileName
"""
import sys
import subprocess
def writexattrs(F,TagList):
""" writexattrs(F,TagList):
writes the list of tags to three xattr fields on a file-by file basis:
"kMDItemFinderComment","_kMDItemUserTags","kMDItemOMUserTags
Uses subprocess instead of xattr module. Slower but no dependencies"""
Result = ""
plistFront = '<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd"><plist version="1.0"><array>'
plistEnd = '</array></plist>'
plistTagString = ''
for Tag in TagList:
plistTagString = plistTagString + '<string>{}</string>'.format(Tag.replace("'","-"))
TagText = plistFront + plistTagString + plistEnd
OptionalTag = "com.apple.metadata:"
XattrList = ["kMDItemFinderComment","_kMDItemUserTags","kMDItemOMUserTags"]
for Field in XattrList:
XattrCommand = 'xattr -w {0} \'{1}\' "{2}"'.format(OptionalTag + Field,TagText.encode("utf8"),F)
if DEBUG:
sys.stderr.write("XATTR: {}\n".format(XattrCommand))
ProcString = subprocess.check_output(XattrCommand, stderr=subprocess.STDOUT,shell=True)
Result += ProcString
return Result
DEBUG = False
if __name__ == "__main__":
if len(sys.argv) < 3:
print __doc__
else:
TagList = [ sys.argv[1] ]
# print TagList
# Or you can hardwire your tags here
# TagList = ['Orange','Green']
FileList = sys.argv[2:]
for FileName in FileList:
writexattrs(FileName, TagList)
Проверьте тег, "инструмент командной строки для управления тегами в файлах Mac OS X 10.9 Mavericks и запроса файлов с этими тегами". в репозитории GitHub есть инструкции по установке (есть пакеты Homebrew и MacPorts).
я добавляю этот ответ, потому что OP попросил сценарий оболочки и пометил его Баш. Я написал этот сервис Automator, который помечает выбранный файл тегами другого файла. Я добавил комментарии, чтобы описать взаимодействие Баша с тегами и цветами с помощью bash-скрипт.
основы
в скриптах и openmeta и Mavericks теги могут быть доступны с помощью команды xattr. Использование без модификаторов, $ xattr [file]
дает список атрибутов. $ xattr -h
дает хорошее руководство по использованию.
теги Mavericks находятся в com.яблоко.метаданные:_kMDItemUserTags, а OpenMeta теги могут быть различными атрибутами. Среди прочих com.apple.metadata:kOMUserTags
, org.openmetainfo:kMDItemOMUserTags
и org.openmetainfo:kOMUserTags
.
Mavericks обрабатывает цвета и теги в разных атрибутах, помещая теги в _kMDItemUserTags и цвета в FinderInfo для каждого файла. Это странный выбор, и это одна из причин, почему Finder борется под давление маркировки. Если у вас 800 файлов с тегами kapow, каждый в другой папке, и вы впоследствии выбрать синий цвет для kapow, Finder должен найти и изменить атрибуты для каждого файла.
вы можете играть с странностью, удалив com.яблоко.Атрибут FinderInfo из помеченного и цветного файла:$ xattr -d com.apple.FinderInfo [file]
. Цвет исчезнет в списках Finder, но тег (и его цвет) останется связанным с файл.
скрипт Bash для импорта тегов из другого файла
в скрипте выбранный файл(ы) в Finder/сохраняются в переменную $tagless, а выбранный поставщик тегов -$tagfull.
TAGFULID=${#@}
TAGFUL=${!TAGFULID}
## Use xattr to read all existing tags:
ATTRS=$(xattr "$TAGFUL")
for f in "$@" ## For every selected file in Finder, do:
do
if("$TAGFUL"="$f") ## Is the supplier of tags is amongst the selected files?
then
break
fi
if [[ "$ATTRS" == *kMDItemUserTags* ]] ## Are there tags?
then
## Load tags:
TAGS=$(xattr -px com.apple.metadata:_kMDItemUserTags "$TAGFUL")
## Write tags:
xattr -wx com.apple.metadata:_kMDItemUserTags "$TAGS" "$f"
fi
if [[ "$ATTRS" == *FinderInfo* ]] ## Are there colours?
then
## Load colour:
FINDERINFO=$(xattr -px com.apple.FinderInfo "$TAGFUL")
## Write colour:
xattr -wx com.apple.FinderInfo "$FINDERINFO" "$f"
fi
done
в Apple Что нового в OS X в нем говорится, что NSURL
обрабатывает теги и тег Общая Файловая Система Resource_Keys дает необходимый ключ как NSURLTagNamesKey
и его значение-это просто массив строк.
вы могли бы дать этой выстрел:
xattr -w com.apple.metadata:_kMDItemUserTags '<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd"><plist version="1.0"><array><string>Orange</string><string>Red</string></array></plist>' $currentFile
вы захотите заменить $currentFile файлом, в который хотите добавить теги, и изменить
<string>Orange</string><string>Red</string>
в список любых тегов, которые вы хотите добавить.
это не охватывает теги, но для изменения цвета метки, один из способов сделать это через команду, как это:
xattr -wx com.apple.FinderInfo \
0000000000000000000400000000000000000000000000000000000000000000 myfile.txt
на 04
похоронен в середине устанавливает цвет файла.
вот скрипт python, который обертывает эту команду, позволяющую установить цвет тега в файле или серии файлов:
import sys
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))
использование:
labelcolor.py [color] *.jpg
где [цвет] - это имя или аббревиатура, как определено ниже:
clear (c), grAy (a), green (g), purple (p),
blue (b), yellow (y), red (r), orange (o)
В Спросить Разные
С несколькими ответами, один из которых является принят:
- можно пометить папку через терминал? (2013-11-15)
здесь, в Stack Overflow, вопрос возник немного раньше (2013-11-01), поэтому я добавлю свой ответ здесь.
openmeta
С открытым исходным кодом на https://code.google.com/p/openmeta/source/browse/trunk/trunk/openmeta
на openmeta
команда, похоже, принимает подход с двумя атрибутами, работая с обоими:
com.apple.metadata:kMDItemOMUserTags
com.apple.metadata:_kMDItemUserTags
пример использования
sh-3.2$ sw_vers
ProductName: Mac OS X
ProductVersion: 10.9.5
BuildVersion: 13F1096
sh-3.2$ uname -a
Darwin gpes3e-gjp4.local 13.4.0 Darwin Kernel Version 13.4.0: Wed Mar 18 16:20:14 PDT 2015; root:xnu-2422.115.14~1/RELEASE_X86_64 x86_64
sh-3.2$ date
Sun 26 Jul 2015 08:00:23 BST
sh-3.2$ rm ~/Desktop/test.txt
sh-3.2$ touch ~/Desktop/test.txt
sh-3.2$ xattr -l ~/Desktop/test.txt
sh-3.2$ ./openmeta
openmeta version 0.1 by Tom Andersen code.google.com/p/openmeta/
Usage: openmeta [options] -p PATH[s]
Note that commas are to be used nowhere - tag lists use quotes for two word tags in output
example (list tags and ratings): openmeta -p PATH
example (list tags and ratings multiple): openmeta -p PATH PATH
example (list tags): openmeta -t -p PATH[s]
example (add tags): openmeta -a foo bar -p PATH[s]
example (add tags with spaces): openmeta -a "three word tag" "foo bar" -p PATH[s]
example (set tags): openmeta -s foo bar -p PATH[s]
example (clear all tags): openmeta -s -p PATH[s]
example (set managed): openmeta -m Y -p PATH[s]
example (set rating 0 - 5 stars): openmeta -r 3.5 -p PATH[s]
example (print rating): openmeta -r -p PATH[s]
example (clear rating): openmeta -r 0.0 -p PATH[s]
example (lousy rating): openmeta -r 0.1 -p PATH[s]
sh-3.2$ ./openmeta -a kerfuffle -p ~/Desktop/test.txt
kerfuffle /Users/gjp22/Desktop/test.txt
sh-3.2$ ./openmeta -p ~/Desktop/test.txt
/Users/gjp22/Desktop/test.txt
tags: kerfuffle
rating: none found
sh-3.2$ xattr -l ~/Desktop/test.txt
com.apple.metadata:kMDItemOMUserTagTime:
00000000 62 70 6C 69 73 74 30 30 33 41 BB 64 BD 3C D4 95 |bplist003A.d.<..|
00000010 F2 08 00 00 00 00 00 00 01 01 00 00 00 00 00 00 |................|
00000020 00 01 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................|
00000030 00 11 |..|
00000032
com.apple.metadata:kMDItemOMUserTags:
00000000 62 70 6C 69 73 74 30 30 A1 01 59 6B 65 72 66 75 |bplist00..Ykerfu|
00000010 66 66 6C 65 08 0A 00 00 00 00 00 00 01 01 00 00 |ffle............|
00000020 00 00 00 00 00 02 00 00 00 00 00 00 00 00 00 00 |................|
00000030 00 00 00 00 00 14 |......|
00000036
com.apple.metadata:_kMDItemUserTags:
00000000 62 70 6C 69 73 74 30 30 A1 01 5B 6B 65 72 66 75 |bplist00..[kerfu|
00000010 66 66 6C 65 0A 30 08 0A 00 00 00 00 00 00 01 01 |ffle.0..........|
00000020 00 00 00 00 00 00 00 02 00 00 00 00 00 00 00 00 |................|
00000030 00 00 00 00 00 00 00 16 |........|
00000038
kOM109SyncDone:
00000000 62 70 6C 69 73 74 30 30 09 08 00 00 00 00 00 00 |bplist00........|
00000010 01 01 00 00 00 00 00 00 00 01 00 00 00 00 00 00 |................|
00000020 00 00 00 00 00 00 00 00 00 09 |..........|
0000002a
sh-3.2$
ограничения других утилит
Apple Finder, например.
после использования Finder для удаления заварухи тег, заварухи остается как тег OpenMeta:
sh-3.2$ date ; xattr -l ~/Desktop/test.txt
Sun 26 Jul 2015 08:02:13 BST
com.apple.metadata:kMDItemOMUserTagTime:
00000000 62 70 6C 69 73 74 30 30 33 41 BB 64 BD 3C D4 95 |bplist003A.d.<..|
00000010 F2 08 00 00 00 00 00 00 01 01 00 00 00 00 00 00 |................|
00000020 00 01 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................|
00000030 00 11 |..|
00000032
com.apple.metadata:kMDItemOMUserTags:
00000000 62 70 6C 69 73 74 30 30 A1 01 59 6B 65 72 66 75 |bplist00..Ykerfu|
00000010 66 66 6C 65 08 0A 00 00 00 00 00 00 01 01 00 00 |ffle............|
00000020 00 00 00 00 00 02 00 00 00 00 00 00 00 00 00 00 |................|
00000030 00 00 00 00 00 14 |......|
00000036
com.apple.metadata:_kMDItemUserTags:
00000000 62 70 6C 69 73 74 30 30 A0 08 00 00 00 00 00 00 |bplist00........|
00000010 01 01 00 00 00 00 00 00 00 01 00 00 00 00 00 00 |................|
00000020 00 00 00 00 00 00 00 00 00 09 |..........|
0000002a
kOM109SyncDone:
00000000 62 70 6C 69 73 74 30 30 09 08 00 00 00 00 00 00 |bplist00........|
00000010 01 01 00 00 00 00 00 00 00 01 00 00 00 00 00 00 |................|
00000020 00 00 00 00 00 00 00 00 00 09 |..........|
0000002a
sh-3.2$
понимание этих ограничений
С вниманием к доменам и соглашениям об именах:разработчик мысли о принятии OpenMeta-ироничное программное обеспечение (2009-03, а теперь в интернет архиве Wayback Machine) напоминает нам, что com.apple.metadata
был для использования Apple, когда OpenMeta (проект не на apple.com
домен) начал ориентированный на Apple com.apple.metadata:kMDItemOMUserTags
подход.
поэтому я не должен ожидать, что программное обеспечение Apple получит или сохранит совместимость с обоими подходами к тегированию.
края делам
в некоторых случаях может быть желательно удалить Яблоко-ориентированной com.apple.metadata:_kMDItemUserTags
теги без снятия OpenMeta-ориентированной com.apple.metadata:kMDItemOMUserTags
теги.
однако это-программно-вероятно, выходит за рамки вопроса, заданного @nacross.
начиная с Mavericks, также можно установить теги цветов в Cocoa, используя NSAppleScript
.
NSURL *fileURL = [NSURL fileURLWithPath:@"/Users/sheaparis/Documents/filezilla_sites.xml"];
//Format the filepath for the AppleScript environment.
// Without this, the file cannot be found.
NSString *filepath = [fileURL path];
NSString *appleScriptFilePath = [filepath stringByReplacingOccurrencesOfString:@"/" withString:@":"];
if ([appleScriptFilePath hasPrefix:@":"]) {
appleScriptFilePath = [appleScriptFilePath substringFromIndex:1];
}
NSLog(@"appleScriptFilePath: %@", appleScriptFilePath);
//Tells Finder to set the Red color tag for the specified file
NSString *sourceString = [NSString stringWithFormat:
@"set theFile to \"%@\" as alias\n"
"tell application \"Finder\" to set label index of theFile to 2", appleScriptFilePath];
NSAppleScript *script = [[NSAppleScript alloc] initWithSource:sourceString];
NSDictionary *scriptErrorDict = nil;
[script executeAndReturnError:&scriptErrorDict];
if (scriptErrorDict) {
NSLog(@"errorDict: %@", scriptErrorDict);
}
Если это выполняется в файле, который имеет только один цвет, то он очищает текущий цвет и задает указанный цвет. Однако если в файле уже задано несколько цветов, он не очищает существующие цвета Перед установкой указанного цвета.
С помощью AppleScript
окружающая среда, отображение цвета как следует:
- 0: Нет
- 1: Оранжевый
- 2: Красный
- 3: желтый
- 4: синий
- 5: фиолетовый
- 6: Зеленый
- 7: серый
начиная с Mavericks, можно получить и установить цветные теги в Cocoa, используя NSURL
.
NSURL
имеет множество свойств, которые можно установить или прочитать через соответствующий setResourceValue:forKey:error:
и getResourceValue:forKey:error:
методы.
С помощью NSURLLabelNumberKey
ключ, вы можете установить цветовые метки, следующим образом:
NSURL *fileURL = [NSURL fileURLWithPath:@"/Users/[username]/Documents/[some_file]"];
NSError *resourceError;
if (![fileURL setResourceValue:@(2) forKey:NSURLLabelNumberKey error:&resourceError]) {
NSLog(@"Error while setting file resource: %@", [resourceError localizedDescription]);
}
если это выполняется в файле, который имеет только один цвет, то он очищает текущий цвет и задает указанный цвет. Однако, если несколько цветов уже установлены в файле, затем он не очищает существующие цвета Перед установкой указанного цвета.
вот отображение значения цвета (на El Capitan):
- @(0): Нет
- @(1): серый
- @(2): Зеленый
- @(3): фиолетовый
- @(4): синий
- @(5): желтый
- @(6): Красный
- @(7): оранжевый
Я не смог установить тег с помощью NSURLLabelColorKey
. Вот мой опыт на El Capitan, с ключами, связанными с "тегами" (цветами):
-
NSURLLabelNumberKey
: смогите быть прочитано / установлено успешно, с номерами 0-7. Любое другое число вернет ошибку. Если установлено несколько тегов, то это вернет индекс первого заданного цвета, поскольку он выполняет числовой поиск по индексам с 1 по 7. Хотя вы можете очистить цвет в Finder, нажав на цвет, программно установив цвет, который уже set не очищает этот цвет. -
NSURLLabelColorKey
: возвращает nil, даже если для файла установлен цветовой тег. Установка значения с помощью этого ключа не имеет эффекта. -
NSURLTagNamesKey
: возвращает массив имен цветов для заданных тегов.