Ist es möglich, einen Ordner über ein Terminal zu markieren?

11

Ist es möglich, eine Datei oder einen Ordner in Mavericks über einen Terminalbefehl zu markieren?

GedankenNebel
quelle
1
Ja ist es. Die Tags werden mit xattr gespeichert / gelesen und in com.apple.metadata: _kMDItemUserTags gespeichert. Möchten Sie eine spezifischere Frage bearbeiten (verwenden Sie möglicherweise Python, um ein Tag mit dem Namen "foo" einfach auf eine bestimmte Datei festzulegen), oder sind Sie nur neugierig, ob dies technisch möglich ist?
bmike
verwandte Frage hier
Asmus
1
@bmike danke, ja ich möchte programmatisch bearbeiten: P
GedankenNebel
In Stack Overflow mit einer Antwort von mir: Wie kann ich Dateien programmgesteuert OS X-Tags hinzufügen? (2013-11-01)
Graham Perrin

Antworten:

23

Sie können xattr verwenden. Dadurch werden die Tags von Datei1 nach Datei2 kopiert:

xattr -wx com.apple.metadata:_kMDItemUserTags "$(xattr -px com.apple.metadata:_kMDItemUserTags file1)" file2;xattr -wx com.apple.FinderInfo "$(xattr -px com.apple.FinderInfo file1)" file2

Die Tags werden in einer Eigenschaftsliste als einzelnes Array von Zeichenfolgen gespeichert:

$ xattr -p com.apple.metadata:_kMDItemUserTags file3|xxd -r -p|plutil -convert xml1 - -o -
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<array>
    <string>Red
6</string>
    <string>new tag</string>
    <string>Orange
7</string>
    <string>Yellow
5</string>
    <string>Green
2</string>
    <string>Blue
4</string>
    <string>Purple
3</string>
    <string>Gray
1</string>
</array>
</plist>

Wenn das kColor-Flag in com.apple.FinderInfo nicht gesetzt ist, zeigt Finder die Kreise für Farben nicht an. Wenn das kColor-Flag auf Orange gesetzt ist und die Datei das rote Tag hat, zeigt der Finder sowohl rote als auch orangefarbene Kreise an. Sie können das kColor-Flag mit AppleScript setzen:

xattr -w com.apple.metadata:_kMDItemUserTags '("Red\n6","new tag")' ~/desktop/file4;osascript -e 'on run {a}' -e 'tell app "Finder" to set label index of (POSIX file a as alias) to item 1 of {2, 1, 3, 6, 4, 5, 7}' -e end ~/desktop/file4

xattr -p com.apple.FinderInfo file|head -n1|cut -c28-29Gibt den Wert der für das kColor-Flag verwendeten Bits aus. Rot ist C, Orange ist E, Gelb ist A, Grün ist 4, Blau ist 8, Magenta ist 6 und Grau ist 2. Das Flag, das den Werten 1 hinzufügen würde, wird in OS X nicht verwendet.

Bearbeiten: Sie können auch Tag verwenden :

tag -l file # list
tag -a tag1 file # add
tag -s red,blue file # set
tag -r \* file # remove all tags
tag -f green # find all files with the green tag
tag -f \* # find all files with tags
tag -m red * # match (print files in * that have the red tag)

Tag kann mit brew install tagoder installiert werden sudo port install tag.

$ tag -h
tag - A tool for manipulating and querying file tags.
  usage:
    tag -a | --add <tags> <file>...     Add tags to file
    tag -r | --remove <tags> <file>...  Remove tags from file
    tag -s | --set <tags> <file>...     Set tags on file
    tag -m | --match <tags> <file>...   Display files with matching tags
    tag -l | --list <file>...           List the tags on file
    tag -f | --find <tags>              Find all files with tags
  <tags> is a comma-separated list of tag names; use * to match/find any tag.
  additional options:
        -v | --version      Display version
        -h | --help         Display this help
        -n | --name         Turn on filename display in output (default)
        -N | --no-name      Turn off filename display in output (list)
        -t | --tags         Turn on tags display in output (find, match)
        -T | --no-tags      Turn off tags display in output (list)
        -g | --garrulous    Display tags each on own line (list, find, match)
        -G | --no-garrulous Display tags comma-separated after filename (default)
        -H | --home         Find tagged files only in user home directory
        -L | --local        Find tagged files only in home + local filesystems (default)
        -R | --network      Find tagged files in home + local + network filesystems
        -0 | --nul          Terminate lines with NUL (\0) for use with xargs -0
Lri
quelle
6

Es ist möglich, Tags über reine Bash-Befehle zu bearbeiten. Es ist keine "Tag" -Verwendung von Drittanbietern erforderlich.

Dieser Befehl listet alle Tags einer Datei ($ src) auf:

xattr -px com.apple.metadata:_kMDItemUserTags "$src" | \
    xxd -r -p - - | plutil -convert json -o - - | sed 's/[][]//g' | tr ',' '\n'

Und so können Sie einer Datei ($ src) ein Tag ($ newtag) hinzufügen:

xattr -wx com.apple.metadata:_kMDItemUserTags \
    "$(xattr -px com.apple.metadata:_kMDItemUserTags "$src" | \
    xxd -r -p - - | plutil -convert json -o - - | sed 's/[][]//g' | tr ',' '\n' | \
    (cat -; echo \"$newtag\") | sort -u | grep . | tr '\n' ',' | sed 's/,$//' | \
    sed 's/\(.*\)/[\1]/' | plutil -convert binary1 -o - - | xxd -p - -)" "$src"

Hier ist ein kleines Shell-Skript, das eine "Tags" -Funktion exportiert. Verwendungszweck:

tags <file>
Lists all tags of a file

tags -add <tag> <file>
Adds tag to a file

Die Funktion kann leicht erweitert werden, um auch das Entfernen zu unterstützen.

tags() {
    # tags system explained: http://arstechnica.com/apple/2013/10/os-x-10-9/9/
    local src=$1
    local action="get"

    if [[ $src == "-add" ]]; then
        src=$3
        local newtag=$2
        local action="add"
    fi

    # hex -> bin -> json -> lines
    local hexToLines="xxd -r -p - - | plutil -convert json -o - - | sed 's/[][]//g' | tr ',' '\n'"

    # lines -> json -> bin -> hex
    local linesToHex="tr '\n' ',' | echo [\$(sed 's/,$//')] | plutil -convert binary1 -o - - | xxd -p - -"

    local gettags="xattr -px com.apple.metadata:_kMDItemUserTags \"$src\" 2> /dev/null | $hexToLines | sed 's/.*Property List error.*//'"

    if [[ $action == "get" ]]; then
        sh -c "$gettags"
    else
        local add="(cat -; echo \\\"$newtag\\\") | sort -u"
        local write="xattr -wx com.apple.metadata:_kMDItemUserTags \"\$($gettags | $add | grep . | $linesToHex)\" \"$src\""

        sh -c "$write"
    fi
}
export -f tags
Márton Sári
quelle
Huch, das sind lange Schlangen! Ich schlug eine Wrapping-Bearbeitung vor. Ich denke, sie könnten besser als kleine Shell-Skripte gemacht werden.
Zigg
Ihr xattr -wxBefehl schlägt fehl, wenn die Datei noch keine Tags enthält. Wie kann ich das vermeiden?
user3932000
Scheint ein Problem mit dem neuesten OS X (El Cap 10.11.4) zu haben. Wenn Sie den xattr -px …Befehl "language:Objective-C\n2"ausführen, den Sie zum Anzeigen der Tags in einem meiner Ordner gegeben haben, erhalten Sie die folgende Ausgabe: (Zeilenumbruch) "platform:iOS\n4". Ehrlich gesagt, wenn Sie Ihren mäßig komplexen Shell-Code in eine Bash-Funktion einbinden möchten, duplizieren Sie einfach den Aufwand für Tags , was den Vorteil hat, dass die Community gut gepflegt ist.
Slipp D. Thompson
@ SlippD.Thompson, wie hat das Einpacken von Shell-Code in eine Bash-Funktion etwas mit der "Aufwandsduplizierung" eines zu kompilierenden Tools zu tun? ... Sie müssen dafür keine Pro-Con-Analyse durchführen und ' tag ', du wählst was du willst. Die Aussage dieser Lösung ist, dass Sie kein Tool eines Drittanbieters benötigen , um die gewünschte Funktionalität zu erreichen.
Márton Sári