Possible de baliser un dossier via un terminal?

11

Est-il possible de baliser un fichier ou un dossier dans mavericks via la commande du terminal?

GedankenNebel
la source
1
Oui, ça l'est. Les balises sont stockées / lues à l'aide de xattr et stockées dans com.apple.metadata: _kMDItemUserTags. Voulez-vous éditer une question plus spécifique (peut-être utiliser python pour définir facilement une balise nommée "foo" dans un fichier spécifique) ou êtes-vous simplement curieux de savoir si c'est techniquement possible?
bmike
question connexe ici
Asmus
1
@bmike merci, ouais je veux éditer par programmation: P
GedankenNebel
Dans Stack Overflow, avec une réponse de ma part: Comment puis-je ajouter des «balises» OS X aux fichiers par programme? (2013-11-01)
Graham Perrin

Réponses:

23

Vous pouvez utiliser xattr. Cela copie les balises de file1 à file2:

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

Les balises sont stockées dans une liste de propriétés sous la forme d'un tableau unique de chaînes:

$ 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>

Si l'indicateur kColor dans com.apple.FinderInfo n'est pas défini, le Finder n'affiche pas les cercles pour les couleurs. Si l'indicateur kColor est défini sur orange et que le fichier a la balise rouge, le Finder affiche les cercles rouge et orange. Vous pouvez définir l'indicateur kColor avec AppleScript:

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-29affiche la valeur des bits utilisés pour l'indicateur kColor. Le rouge est C, l'orange est E, le jaune est A, le vert est 4, le bleu est 8, le magenta est 6 et le gris est 2. Le drapeau qui ajouterait 1 aux valeurs n'est pas utilisé sous OS X.

Modifier: vous pouvez également utiliser la balise :

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 peut être installé avec brew install tagou 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
la source
6

Il est possible de manipuler des balises via des commandes bash pures. Il n'est pas nécessaire d'utiliser un "tag" tiers.

Cette commande répertorie toutes les balises d'un fichier ($ src):

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

Et voici comment vous pouvez ajouter une balise ($ newtag) à un fichier ($ src):

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"

Voici un petit script shell qui exporte une fonction "tags". Usage:

tags <file>
Lists all tags of a file

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

La fonction peut également être facilement étendue pour prendre en charge la suppression.

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
la source
Oui, ce sont de longues files d'attente! J'ai suggéré une édition enveloppante. Je pense que cela pourrait être mieux fait en tant que petits scripts shell.
zigg
Votre xattr -wxcommande échoue lorsque le fichier ne contient pas encore de balises. Comment puis-je éviter ça?
user3932000
Semble avoir un problème dans le dernier OS X (El Cap 10.11.4). L'exécution de la xattr -px …commande que vous avez donnée pour afficher les balises sur l'un de mes dossiers donne la sortie suivante: "language:Objective-C\n2"(nouvelle ligne) "platform:iOS\n4". Honnêtement, si vous allez encapsuler votre code shell modérément complexe dans une fonction bash, vous dupliquez simplement l'effort de tag , ce qui a l'avantage d'être bien entretenu par la communauté.
Slipp D. Thompson,
@ SlippD.Thompson, comment l'enveloppement du code shell dans une fonction bash a-t-il quelque chose à voir avec la "duplication d'effort" d'un outil à compiler? ... Vous n'avez pas à donner une analyse pro-con pour cela et ' tag ', vous choisissez ce que vous voulez. L'énoncé de cette solution est que vous n'avez pas besoin d' un outil tiers pour obtenir la fonctionnalité souhaitée.
Márton Sári