¿Es posible etiquetar una carpeta a través de la terminal?

11

¿Es posible etiquetar un archivo o carpeta en disidentes mediante un comando de terminal?

GedankenNebel
fuente
1
Sí lo es. Las etiquetas se almacenan / leen usando xattr y se almacenan en com.apple.metadata: _kMDItemUserTags. ¿Desea editar en una pregunta más específica (quizás use python para configurar fácilmente una etiqueta llamada "foo" en un archivo específico) o simplemente tiene curiosidad si es técnicamente posible?
bmike
pregunta relacionada aquí
Asmus
1
@bmike gracias, sí, quiero editar mediante programación: P
GedankenNebel
En Stack Overflow, con una respuesta mía: ¿cómo puedo agregar "etiquetas" de OS X a los archivos mediante programación? (01/11/2013)
Graham Perrin

Respuestas:

23

Puedes usar xattr. Esto copia las etiquetas del archivo1 al archivo2:

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

Las etiquetas se almacenan en una lista de propiedades como una sola matriz de cadenas:

$ 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 la bandera kColor en com.apple.FinderInfo no está activada, Finder no muestra los círculos para los colores. Si el indicador kColor está configurado en naranja y el archivo tiene la etiqueta roja, Finder muestra círculos rojos y naranjas. Puede configurar el indicador kColor con 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-29imprime el valor de los bits utilizados para el indicador kColor. El rojo es C, el naranja es E, el amarillo es A, el verde es 4, el azul es 8, el magenta es 6 y el gris es 2. La bandera que agregaría 1 a los valores no se usa en OS X.

Editar: también puedes usar la etiqueta :

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)

La etiqueta se puede instalar con brew install tago 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
fuente
6

Es posible manipular etiquetas mediante comandos de bash puro. No hay necesidad de una utilidad de "etiqueta" de terceros.

Este comando enumera todas las etiquetas de un archivo ($ src):

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

Y así es como puede agregar una etiqueta ($ newtag) a un archivo ($ 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"

Aquí hay un pequeño script de shell que exporta una función de "etiquetas". Uso:

tags <file>
Lists all tags of a file

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

La función podría extenderse fácilmente para admitir la eliminación también.

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
fuente
¡Ay, esas son largas colas! Sugerí una edición de envoltura. Sin embargo, creo que podrían hacerse mejor como pequeños scripts de shell.
zigg
Su xattr -wxcomando falla cuando el archivo ya no tiene ninguna etiqueta. ¿Cómo puedo evitar esto?
user3932000
Parece tener algún problema en el último OS X (El Cap 10.11.4). Al ejecutar el xattr -px …comando que has dado para mostrar las etiquetas en una de mis carpetas da el siguiente resultado: "language:Objective-C\n2"(salto de línea) "platform:iOS\n4". Honestamente, si va a envolver su código de shell moderadamente complejo en una función bash, simplemente está duplicando el esfuerzo de la etiqueta , que tiene la ventaja de estar bien mantenido por la comunidad.
Slipp D. Thompson
@ SlippD.Thompson, cómo está terminando código shell en una función fiesta nada que ver con la "duplicación esfuerzo" de una herramienta a ser compilado? ... Usted no tiene que dar un análisis de pros y contras de este y ' etiqueta ', eliges lo que quieras. La declaración de esta solución es que no necesita una herramienta de terceros para lograr la funcionalidad deseada.
Márton Sári