Czy można oznaczyć folder za pomocą terminala?

11

Czy możliwe jest oznaczenie pliku lub folderu w mavericks za pomocą polecenia terminalu?

GedankenNebel
źródło
1
Tak to jest. Znaczniki są przechowywane / odczytywane za pomocą xattr i przechowywane w com.apple.metadata: _kMDItemUserTags. Czy chcesz edytować bardziej szczegółowe pytanie (być może użyj Pythona, aby łatwo ustawić znacznik o nazwie „foo” w określonym pliku), czy jesteś po prostu ciekawy, czy jest to technicznie możliwe?
bmike
powiązane pytanie tutaj
Asmus
1
@bike dzięki, tak Chcę edytować programowo: P
GedankenNebel
W przepełnieniu stosu, z odpowiedzią ode mnie: Jak mogę programowo dodać „tagi” OS X do plików? (2013-11-01)
Graham Perrin

Odpowiedzi:

23

Możesz użyć xattr. Spowoduje to skopiowanie znaczników z pliku 1 do pliku 2:

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

Znaczniki są przechowywane na liście właściwości jako pojedyncza tablica ciągów:

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

Jeśli flaga kColor w com.apple.FinderInfo jest wyłączona, Finder nie pokazuje okręgów dla kolorów. Jeśli flaga kColor jest ustawiona na pomarańczowy, a plik ma czerwony znacznik, Finder pokazuje zarówno czerwone, jak i pomarańczowe kółka. Możesz ustawić flagę kColor za pomocą 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-29wypisuje wartość bitów użytych dla flagi kColor. Czerwony to C, pomarańczowy to E, żółty to A, zielony to 4, niebieski to 8, magenta to 6, a szary to 2. Flaga, która dodaje 1 do wartości, nie jest używana w OS X.

Edycja: możesz także użyć tagu :

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 można zainstalować za pomocą brew install taglub 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
źródło
6

Możliwe jest manipulowanie znacznikami za pomocą poleceń czysto bashowych. Nie ma potrzeby używania zewnętrznego tagu.

To polecenie wyświetla wszystkie tagi pliku ($ src):

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

A oto jak możesz dodać tag ($ newtag) do pliku ($ 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"

Oto mały skrypt powłoki, który eksportuje funkcję „tagów”. Stosowanie:

tags <file>
Lists all tags of a file

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

Funkcję tę można łatwo rozszerzyć, aby obsługiwała również usuwanie.

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
źródło
Yikes, to są długie kolejki! Zaproponowałem edycję zawijania. Sądzę jednak, że lepiej byłoby je wykonać jako małe skrypty powłoki.
zigg
Twoje xattr -wxpolecenie kończy się niepowodzeniem, gdy plik nie ma już żadnych tagów. Jak mogę tego uniknąć?
user3932000,
Wygląda na to, że ma jakiś problem w najnowszym OS X (El Cap 10.11.4). Uruchomienie xattr -px …polecenia, które podałeś, aby pokazać tagi w jednym z moich folderów, daje następujący wynik: "language:Objective-C\n2"(nowa linia) "platform:iOS\n4". Szczerze mówiąc, jeśli zamierzasz zawinąć swój umiarkowanie skomplikowany kod powłoki w funkcję bash, po prostu powielasz wysiłek związany z tagiem , który ma tę zaletę, że jest dobrze utrzymywany przez społeczność.
Slipp D. Thompson
@ SlippD.Thompson, w jaki sposób zawijanie kodu powłoki do funkcji bash ma coś wspólnego z „kopiowaniem wysiłku” przyszłego narzędzia do kompilacji? ... Nie musisz przedstawiać analizy pro-con dla tego i „ tag ”, wybierasz, co chcesz. Stwierdzeniem tego rozwiązania jest to , że nie potrzebujesz narzędzia innej firmy, aby osiągnąć pożądaną funkcjonalność.
Márton Sári