How can I add OS X “tags” to files programmaticall

2019-03-07 19:49发布

Since Mavericks, OS X has had the ability to tag & colour files in Finder.

finder tags

Is there any way to add tags to files through Cocoa APIs or via a shell command?

10条回答
我只想做你的唯一
2楼-- · 2019-03-07 19:50

The OpenMeta framework is a third-party standard for adding metadata to OS X files using extended attributes. It is used by a number of third-party applications.

Or you can use the XATTR command to manipulate the extended attributes via command line.

查看更多
Root(大扎)
3楼-- · 2019-03-07 19:56

Check out tag, "a command line tool to manipulate tags on Mac OS X 10.9 Mavericks files, and to query for files with those tags". The GitHub repository has installation instructions (there are Homebrew and MacPorts packages).

查看更多
够拽才男人
4楼-- · 2019-03-07 19:58

Sorry for adding another answer, but the one related to setting Label colors was pretty long already. Here is an excerpt from a python script that I use to set the User Tags. It seems to work to make things searchable, but not sure if the tags will show up correctly. Usage is basically:

tagfile.py "Tag Name" FileOrFolderName

Code below.

#! /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)
查看更多
姐就是有狂的资本
5楼-- · 2019-03-07 20:00

You could give this a shot:

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

You'll want to replace $currentFile with the file you'd like to add tags to, and change

<string>Orange</string><string>Red</string>

to a list of whatever tags you want to add.

查看更多
时光不老,我们不散
6楼-- · 2019-03-07 20:02

This does not cover tags, but for changing label colors, one way to do it is through a command like this:

xattr -wx com.apple.FinderInfo \
0000000000000000000400000000000000000000000000000000000000000000 myfile.txt

The 04 buried in the middle is setting the file color.

Here is a python script which wraps that command lets you set the tag color on a file or series of files:

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 is:

  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)
查看更多
Bombasti
7楼-- · 2019-03-07 20:05

In Ask Different

With multiple answers, one of which is accepted:


Here in Stack Overflow the question arose slightly earlier (2013-11-01) so I'll add my answer here.

openmeta

Open source at https://code.google.com/p/openmeta/source/browse/trunk/trunk/openmeta

The openmeta command appears to take a dual attribute approach, working with both:

  • com.apple.metadata:kMDItemOMUserTags
  • com.apple.metadata:_kMDItemUserTags

Example 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 of other utilities

Apple Finder, for example.

After using Finder to remove the kerfuffle tag, kerfuffle remains as an OpenMeta tag:

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$ 

Understanding those limitations

With attention to domains and naming conventions: Developer thoughts on adopting OpenMeta – Ironic Software (2009-03, and now in the Internet Archive Wayback Machine) reminds us that com.apple.metadata was for use by Apple when OpenMeta (a project not in the apple.com domain) began the Apple-oriented com.apple.metadata:kMDItemOMUserTags approach.

So I should not expect Apple software to gain or maintain compatibility with both approaches to tagging.


Edge cases

In some cases it may be desirable to remove Apple-oriented com.apple.metadata:_kMDItemUserTags tags without removing OpenMeta-oriented com.apple.metadata:kMDItemOMUserTags tags.

However, doing so – programmatically – is probably beyond the scope of the question asked by @nacross.

查看更多
登录 后发表回答