Comment puis-je ajouter OS X "tags" aux fichiers par programmation?
depuis Mavericks, OS X a eu la possibilité d'étiqueter et de colorer des fichiers dans Finder.
y a-t-il un moyen d'ajouter des tags à des fichiers via les API de Cocoa ou via une commande shell?
10 réponses
Désolé d'ajouter une autre réponse, mais celle liée à la définition des couleurs des étiquettes était déjà assez longue. Voici un extrait d'un script python que j'utilise pour définir les Balises. Il semble fonctionner pour rendre les choses searchable, mais pas sûr si les étiquettes vont apparaître correctement. L'Usage est essentiellement:
tagfile.py "Tag Name" FileOrFolderName
Code ci-dessous.
#! /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)
Check out tag,"un outil en ligne de commande pour manipuler les tags sur Mac OS X 10.9 Mavericks fichiers, et pour demander des fichiers avec ces tags". le dépôt GitHub a des instructions d'installation (il y a des paquets Homebrew et MacPorts).
j'ajoute cette réponse, parce que OP a demandé un script shell et l'a étiqueté bash . J'ai écrit Ce service D'automate, qui identifie le fichier sélectionné avec les étiquettes d'un autre fichier. J'ai ajouté des commentaires pour souligner l'utilisation de l'interaction de bash avec les tags et les couleurs en utilisant l'écriture de bash.
de base
dans les scripts les tags OpenMeta et Mavericks sont accessibles avec la commande xattr . L'utiliser sans modifier, $ xattr [file]
, donne une liste d'attributs. $ xattr -h
donne un bon guide d'utilisation.
les étiquettes de Mavericks sont dans com.Apple.métadonnées: _kMDItemUserTags, tandis que les tags OpenMeta peuvent être dans une variété d'attributs. Entre autres com.apple.metadata:kOMUserTags
, org.openmetainfo:kMDItemOMUserTags
et org.openmetainfo:kOMUserTags
.
Mavericks gère les couleurs et les étiquettes dans différents attributs, en plaçant les étiquettes dans _kMDItemUserTags et les couleurs dans FinderInfo pour chaque fichier. C'est un choix bizarre, et c'est l'une des raisons pour lesquelles Finder lutte sous la pression du marquage. Si vous avez 800 fichiers marqués kapow , chacun dans un dossier différent, et que vous choisissez ensuite la couleur bleue pour kapow , Finder doit trouver et modifier les attributs pour chaque fichier.
vous pouvez jouer avec l'étrangeté en enlevant le com.Apple.Attribut FinderInfo à partir d'un fichier coloré: $ xattr -d com.apple.FinderInfo [file]
. La couleur disparaîtra dans les listes de Finder, mais l'étiquette (et sa couleur) reste associée au fichier.
script Bash pour importer des balises à partir d'un autre fichier
dans le script, le(S) fichier (s) sélectionné (s) dans Finder est/sont enregistrés à la variable $tagless , et le fournisseur choisi de tags est $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 Ce qui est Nouveau dans OS X il affirme que NSURL
poignées de balises, et le Système de Fichiers Commun Resource_Keys donne la clé requise NSURLTagNamesKey
et les membres de sa valeur est un tableau de chaînes de caractères.
le OpenMeta framework est une norme de tiers pour ajouter des métadonnées aux fichiers OS X en utilisant des attributs étendus. Il est utilisé par un certain nombre d'applications tierces.
ou vous pouvez utiliser la commande XATTR pour manipuler les attributs étendus via la ligne de commande.
Vous pourriez donner ce un coup:
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
vous voulez remplacer $currentFile par le fichier auquel vous voulez ajouter des balises, et changer
<string>Orange</string><string>Red</string>
à une liste de toutes les étiquettes que vous voulez ajouter.
cela ne couvre pas les étiquettes, mais pour changer les couleurs des étiquettes, une façon de le faire est par une commande comme celle-ci:
xattr -wx com.apple.FinderInfo \
0000000000000000000400000000000000000000000000000000000000000000 myfile.txt
le 04
enfoui au milieu définit la couleur du fichier.
voici un script python qui enveloppe cette commande vous permet de définir la couleur de la balise sur un fichier ou une série de fichiers:
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))
Usage:
labelcolor.py [color] *.jpg
où [couleur] est un nom ou l'abréviation défini ci-après:
clear (c), grAy (a), green (g), purple (p),
blue (b), yellow (y), red (r), orange (o)
À Poser Des Différents
avec plusieurs réponses, dont l'une est acceptée :
- possibilité d'étiqueter un dossier via un terminal? (2013-11-15)
ici, dans Stack Overflow la question a été soulevée un peu plus tôt (2013-11-01) donc je vais ajouter ma réponse ici.
openmeta
Open source à https://code.google.com/p/openmeta/source/browse/trunk/trunk/openmeta
la commande openmeta
semble adopter une approche à double attribut, en travaillant avec les deux:
-
com.apple.metadata:kMDItemOMUserTags
-
com.apple.metadata:_kMDItemUserTags
exemple d'usage
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$
Limitations des autres services publics
Apple Finder, par exemple.
après avoir utilisé Finder pour supprimer le kerfuffle étiquette, kerfuffle reste comme une étiquette 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$
la Compréhension de ces limitations
avec attention aux domaines et aux conventions de nommage: réflexions des développeurs sur L'adoption du logiciel OpenMeta – Ironic (2009-03, et maintenant dans les archives Internet Wayback Machine) nous rappelle que com.apple.metadata
était destiné à Apple quand OpenMeta (un projet pas dans le domaine apple.com
) a commencé l'approche com.apple.metadata:kMDItemOMUserTags
orientée Apple.
donc je ne devrais pas m'attendre à ce que le logiciel Apple gagne ou maintienne la compatibilité avec les deux approches de marquage.
cas limites
dans certains cas, il peut être souhaitable de supprimer Pomme orientée com.apple.metadata:_kMDItemUserTags
tags sans enlever OpenMeta orientée com.apple.metadata:kMDItemOMUserTags
balises.
cependant, le faire-programmatiquement – dépasse probablement le cadre de la question posée par @nacross.
à partir de Mavericks, il est également possible de définir des tags de couleurs en cacao, en utilisant 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);
}
Si c'est exécutée sur un fichier qui n'a qu'une couleur, puis il efface la couleur, et définit la couleur spécifiée. Cependant, si plusieurs couleurs sont déjà définies sur le fichier, alors il ne nettoie pas les couleurs existantes avant de définir la couleur spécifiée.
utilisant l'environnement AppleScript
, la cartographie des couleurs est la suivante:
- 0: Aucun
- 1: Orange
- 2: rouge
- 3: jaune
- 4: Bleu
- 5: Pourpre
- 6: Vert
- 7: Grey
à partir de Mavericks, il est possible d'obtenir et de définir des étiquettes de couleur en cacao, en utilisant NSURL
.
NSURL
possède un grand nombre de propriétés qui peuvent être définies ou lues, à travers les méthodes respectives setResourceValue:forKey:error:
et getResourceValue:forKey:error:
.
en utilisant la touche NSURLLabelNumberKey
, vous pouvez définir les balises de couleur, comme suit:
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]);
}
Si c'est exécutée sur un fichier qui n'a qu'une couleur, puis il efface la couleur, et définit la couleur spécifiée. Cependant, si plusieurs couleurs sont déjà définies sur le fichier, alors il ne nettoie pas les couleurs existantes avant de définir la couleur spécifiée.
Voici la cartographie valeur-couleur (sur El Capitan):
- @(0): néant 1519240920"
- @(1): Grey
- @(2): Vert
- @(3): Violet
- @(4): Bleu
- @(5): Jaune
- @(6): Rouge
- @(7): Orange
Je n'ai pas été en mesure de définir une étiquette en utilisant NSURLLabelColorKey
. Voici mon expérience sur El Capitan, avec les clés liées aux 'tags' (couleurs):
-
NSURLLabelNumberKey
: peut être lu / réglé avec succès, avec des nombres 0-7. Tout autre nombre retournera une erreur. S'il y a plusieurs tags définis, alors cela retournera l'index du première couleur qui est définie, car il recherche numériquement à travers les index 1 à 7. Bien que vous pouvez effacer une couleur dans Finder en cliquant sur la couleur, le réglage programmatique d'une couleur qui est déjà réglée ne clarifie pas cette couleur. -
NSURLLabelColorKey
: renvoie zéro, même si une étiquette de couleur est définie pour un fichier. Définir une valeur avec cette clé n'a aucun effet. -
NSURLTagNamesKey
: renvoie un tableau des noms de couleur pour les tags qui sont définis.