如何以编程方式将OS X“标签”添加到文件中?

时间:2013-11-01 03:36:15

标签: macos cocoa metadata command-line-tool

自从小牛队以来,OS X已经具备了标记和标记功能。 Finder中的颜色文件。

finder tags

有没有办法通过Cocoa API或shell命令向文件添加标签?

10 个答案:

答案 0 :(得分:11)

很抱歉添加了另一个答案,但与设置标签颜色相关的答案已经很久了。这是我用来设置用户标签的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)

答案 1 :(得分:9)

签出标签,&#34;一个命令行工具,用于操作Mac OS X 10.9 Mavericks文件上的标签,以及查询带有这些标签的文件&#34;。 The GitHub repository has installation instructions(有Homebrew和MacPorts包)。

答案 2 :(得分:5)

我添加了这个答案,因为OP要求提供一个shell脚本并将其标记为 bash 。我编写了这个Automator服务,它使用另一个文件的标签标记所选文件。我添加了注释,概述了使用bash脚本使用bash与标记和颜色的交互。

基本

在脚本中,可以使用 xattr 命令访问OpenMeta和Mavericks标记。使用它而不使用修饰符$ xattr [file],会给出一组设置属性。 $ xattr -h提供了很好的使用指南。

Mavericks的标签位于com.apple.metadata:_kMDItemUserTags中,而OpenMeta标签可以具有各种属性。其中包括com.apple.metadata:kOMUserTagsorg.openmetainfo:kMDItemOMUserTagsorg.openmetainfo:kOMUserTags

Mavericks通过在_kMDItemUserTags中放置标签并在FinderInfo中为每个文件放置颜色来处理不同属性中的颜色和标签。这是一个奇怪的选择,这也是Finder在标记压力下挣扎的原因之一。如果您有800个文件标记为 kapow ,每个文件位于不同的文件夹中,然后您为 kapow 选择蓝色,则Finder必须查找并更改每个文件的属性。

您可以通过从已标记的彩色文件中删除com.apple.FinderInfo属性来解决这个问题:$ xattr -d com.apple.FinderInfo [file]。颜色将在Finder列表中消失,但标记(及其颜色)仍与文件关联。

用于从其他文件导入标签的Bash脚本

在脚本中,Finder中的选定文件将保存到变量 $ tagless ,所选标签供应商为 $ tagfull 。< / p>

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

The Automator service

答案 3 :(得分:4)

在Apple的What's New in OS X中,它指出NSURL处理标记,Common File System Resource_Keys将所需的密钥作为NSURLTagNamesKey,并声明其值只是一个字符串数组。< / p>

答案 4 :(得分:2)

OpenMeta框架是使用扩展属性向OS X文件添加元数据的第三方标准。它被许多第三方应用程序使用。

或者您可以使用XATTR命令通过命令行操作扩展属性。

答案 5 :(得分:2)

你可以给this一个镜头:

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>

到您要添加的任何标签的列表。

答案 6 :(得分:1)

这不包括标签,但是为了更改标签颜色,一种方法是通过这样的命令:

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

其中[color]是下面定义的名称或缩写:

    clear (c), grAy (a), green (g), purple (p), 
    blue (b), yellow (y), red (r), orange (o)

答案 7 :(得分:0)

在Ask Different

有多个答案,其中一个是accepted

这里的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删除 kerfuffle 标记后, kerfuffle 仍然是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$ 

了解这些限制

关注域和命名约定:Developer thoughts on adopting OpenMeta – Ironic Software(2009-03,现在在Internet Archive Wayback Machine中)提醒我们,当OpenMeta(项目com.apple.metadata > {/ 1}}域中不开始采用面向Apple的apple.com方法。

所以我不应指望Apple软件能够获得或保持与这两种标记方法的兼容性。

边缘情况

在某些情况下,可能需要移除 Apple - 导向的com.apple.metadata:kMDItemOMUserTags代码,而无需移除 OpenMeta -oriented {{1标签。

然而,这样做 - 以编程方式 - 可能超出了@nacross提出的问题的范围。

答案 8 :(得分:0)

从Mavericks开始,可以使用heroku run rails c在Cocoa中获取和设置颜色标记。

NSURL有一系列可以通过相应的NSURLsetResourceValue:forKey:error:方法设置或阅读的属性。

使用getResourceValue:forKey:error:键,您可以设置颜色标记,如下所示:

NSURLLabelNumberKey

如果在仅有一种颜色的文件上执行此操作,则会清除当前颜色,并设置指定的颜色。但是,如果文件上已经设置了多种颜色,则在设置指定颜色之前不会清除现有颜色。

这是价值 - 颜色映射(在El Capitan上):

  • @(0):无
  • @(1):Gray
  • @(2):Green
  • @(3):紫色
  • @(4):Blue
  • @(5):黄色
  • @(6):红色
  • @(7):Orange

我无法使用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上的经历,其中包含与&#39;标签相关的按键。 (色):

  • NSURLLabelColorKey:可以成功读取/设置,数字为0-7。任何其他数字都将返回错误。如果设置了多个标签,那么这将返回设置的第一种颜色的索引,因为它通过索引1到7进行数字搜索。虽然您可以通过单击颜色在Finder中清除颜色,但是以编程方式设置颜色已经设定的颜色不清楚。
  • NSURLLabelNumberKey:即使为文件设置了颜色标记,也会返回nil。使用此键设置值无效。
  • NSURLLabelColorKey:返回已设置标记的颜色名称数组。

答案 9 :(得分:0)

从Mavericks开始,也可以使用NSURLTagNamesKey在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); } 环境,颜色映射如下:

  • 0:无
  • 1:橙色
  • 2:红色
  • 3:黄色
  • 4:蓝色
  • 5:紫色
  • 6:绿色
  • 7:格雷