「Finderで付けた複数カラー・タグ」を「Terminalコマンドで如何に処理」すればよいか?

近くのトピックに触発されて、Finderの動作をエミュレートするスクリプトを作成中です。


手始めに「Finderの表示モード;Date Modified ^」をyyyy-mm-dd-HH:MMで表示するスクリプトを作って見ました。


結果、Finderよりも視認性が良くて良いです。出来てみると「Finderで付けたカラー・タグ」を付けたくなり、探してみましたがファイルに一色のタグの場合は読めるものの、複数タグの場合は、最後に付けたタグしか読めません。


テスト用に作ったフォルダ中の「Finderのキャプチュア」を下図に示します。



上記フォルダ中で、実施したコマンドは;

「xattr -p -x com.apple.FinderInfo *」

その出力を図2に示します;


以上、宜しくお願いします。

Mac mini, macOS 10.14

投稿日 2019/05/31 09:42

返信
スレッドに付いたマーク ランキングトップの返信

投稿日 2019/06/01 20:28

タグの取得だけで良いなら、最初のコメントに書いたように mdls や xattr でできますよ。これなら簡単なシェルスクリプトでいけるはず。


あと、タグの設定については、


xattr -p com.apple.metadata:_kMDItemUserTags "file" | xxd -r -p | plutil -convert xml1 -o - -- -


↑これと逆のことをやれば xattr でできます。


#!/bin/bash

#
# usage: bash me.sh file1 file2 ...
#

tags='["01\n7","02\n6"]'

[[ $# > 0 ]] || { echo "usage: bash $0 file1 file2 ..." >&2; exit 1; }

for f in "$@"; do
    tags_value=$(echo "$tags" | plutil -convert binary1 -o - -- - | xxd -p)    
    xattr -wx com.apple.metadata:_kMDItemUserTags "$tags_value" "$f"
done


ただし、この場合は Finder や setResourceValue:forKey:error: メソッドとは異なり、設定されるのは「タグのみ」となります。


tags='["01\n7","02\n6"]' のところは '["タグ名\nラベルインデックス"]' または '["タグ名"]' みたいな感じで、JSON の配列で指定してください。


返信: 59
スレッドに付いたマーク ランキングトップの返信

2019/06/01 20:28 mNeji への返信

タグの取得だけで良いなら、最初のコメントに書いたように mdls や xattr でできますよ。これなら簡単なシェルスクリプトでいけるはず。


あと、タグの設定については、


xattr -p com.apple.metadata:_kMDItemUserTags "file" | xxd -r -p | plutil -convert xml1 -o - -- -


↑これと逆のことをやれば xattr でできます。


#!/bin/bash

#
# usage: bash me.sh file1 file2 ...
#

tags='["01\n7","02\n6"]'

[[ $# > 0 ]] || { echo "usage: bash $0 file1 file2 ..." >&2; exit 1; }

for f in "$@"; do
    tags_value=$(echo "$tags" | plutil -convert binary1 -o - -- - | xxd -p)    
    xattr -wx com.apple.metadata:_kMDItemUserTags "$tags_value" "$f"
done


ただし、この場合は Finder や setResourceValue:forKey:error: メソッドとは異なり、設定されるのは「タグのみ」となります。


tags='["01\n7","02\n6"]' のところは '["タグ名\nラベルインデックス"]' または '["タグ名"]' みたいな感じで、JSON の配列で指定してください。


2019/07/29 10:17 hohokihai への返信

hohokihaiさん、


返信が遅れまして、申し訳ありませんでした。


『経緯』


tagnamesを動かした後で、shell-scriptで運用上のトライアルをしているうちに、問題点は次だと思いました;

  • 一つのファイルに、同一色の複数別名(exp.: red1,red2,...)を必要となる。すなわち
  • % tagnames -a red1,red2 xxx


色々とトライしていた時に、タイポで;

• % tagnames -a red1,red1 xxx

としたのですが、なんと動きました!


そこでFinderの"Preferences --> Tags"で、8個の一文字定義(r|o|y|g|b|p|s|z)を用意しました、下図0;



これらを用いて、Tagsを複数個設定してみると

  • % tagnames -a r,o,y,g,b,p,s FileName↩︎ #==> Finderでは、左からs,p,bとタグがつく・
  • % tagnames FileName↩︎ #==> s↩︎p↩︎b↩︎
  • 3個まではFinderで表示されますが、それ以上は無視されます。しかしtagnamesで設定を読むと; % tagnames xxx #==> s↩︎p↩︎g↩︎y↩︎o↩︎r↩︎

と完全に情報は保存されている様です。


そこて、今後のスクリプトの運用指針を決めました;

  • タグの設定数は5個までとして、
  • タイプしたタグは左右反転して、「タイプ順とFinderの順」が一致することとした。

後は、使いながら2つのスクリプトを作りました;

  • TagNames.wite FileName aoygb↩︎ #==> (aoygb)
  • TagNames.read FileName↩︎ #==> (aoygb)

タグを消すには、タグの設定を入れないで;

  • TagNames.wite FileName↩︎ #==> ''
  • TagNames.read FileName↩︎ #==> (_____)


実際は、aliasを利用;

  • tgw='TagNames.wite '
  • tgr='TagNames.read '

『運用結果』


自作のスクリプトの管理が不十分なので、Finderの「Date Modified ^」に相当するスクリプト「ldm」を使っていたので、これにタグを読み込む様にしました、下図1;



ここで、ファイル「x」のtagsの表示;

  • ldmでは「_yrys」が
  • Finderの左ペインでは「yry」と短縮されるが、
  • Finderの右ペインでは「syry」と逆順ながら4色が保存されています。



上記のテストではDesktopを見ながらテストをしたので、ファイルの名前順にtagsとファイル名を表示するだけのスクリプト群を作りました、下図2;



これらのスクリプトはiCloudDrive中のヂレクトリのチェックに使い勝手が良さそうです;

  • ln : ディレクトリ内の俯瞰ができる。
  • lnts : 興味点のランキングが見える。


『気がついた点』

  • zshのディレクトリは整頓不足の為に、ldmで10s程かかる。完全にSwiftにすると、どれほど高速になるか?
  • FinderのCUI化の為の、Terminal技法を探したくなった。
  • Orangeの色の設定が間違っているようだ。再検討が必要。
  • 複数のターミナルを、それぞれ「固有のDesktop-nに、固有位置に設定する」Swiftが作りたくなってきた。



以上、詳細なご指導に感謝いたします。


2019/05/31 15:50 mNeji への返信

com.apple.FinderInfo に保存されているのはラベルの情報。タグは com.apple.metadata:_kMDItemUserTags です。


情報を取得するだけなら mdls を使うと良いでしょう。

mdls "file"


ーーーーー


タグ

mdls -raw -name kMDItemUserTags -nullMarker '()' "file"


また、xml や json で出力すると解析しやすいです。


xml

mdls -raw -name kMDItemUserTags -nullMarker '()' "file" | plutil -convert xml1 -o - -- -


json

mdls -raw -name kMDItemUserTags -nullMarker '()' "file" | plutil -convert json -o - -- -


ちなみに xattr ならこんな感じ。

xattr -p com.apple.metadata:_kMDItemUserTags "file" | xxd -r -p | plutil -convert xml1 -o - -- -


ーーーーー


ラベル

mdls -raw -name kMDItemFSLabel "file"


ラベルは色の名前ではなく、インデックスで返されます。色の割り当てはこんな感じ。


0 : なし
1 : グレー
2 : グリーン
3 : パープル
4 : ブルー
5 : イエロー
6 : レッド
7 : オレンジ


ーーーーー


あと、タグとラベルの取得/設定は下記を見ながらスクリプトを書くと良いと思います。


NSURLResourceKey - Foundation | Apple Developer Documentation

https://developer.apple.com/documentation/foundation/nsurlresourcekey?language=objc


2019/06/07 02:15 Hiro__S への返信

Hiro.Sさん、


出来ました! 夢に見た「赤tagの3連続」です。


思い余ってSafariからでコピー&ペーストしたtags1.pyと、前回Firefoxから写経したtags.pyをエディタで比較すると一致してそうですが、diffだと多量な不一致が...。


〆たと思い、「tags1.py -t Red -t R1 -t R2 z」としたのが上の図です。老人なりに感激しました。


今後の勉強としては;

  • pythonの簡単な文法についてはwebにありそうなので、泥縄で遊んでみます。
  • applescriptは完全に落ち溢れたままです。かわりにSwiftに手を出そうかと...。


当面は「tags.py」をシェル・スクリプトから呼び出す積りです。


で本スレッドの目的は、段々と、明確になってきました;

file名の前に「4つのタグを配置」して、その長さでレイトを表す(擬似棒グラフ)ようにします。色については;

  • 赤: Apple関係
  • 青: Mozills関係
  • 緑: Qiita関係
  • 橙: 興味ある分野関係
  • 黄: 一般の検索
  • 灰: Google検索
  • 紫: 未定です。


なお、青はダーク・バックグランドでは見にくいので、色味を修正したり、他の区別しやすい色を探してみたいです。



最後に「改訂版tags.py」の公開を頂き、深く感謝申し上げます。

2019/05/31 16:05 mNeji への返信

ラベルを設定する JXA スクリプト


set_label(7, f) のところは適宜変更してください。


//
// usage: osascript -l JavaScript me.applescript file1 file2 ...
//

function run(argv) {
    let argc = argv.length;

    if (argc < 1) {
        return 1;
    }

    for (let f of argv) {
        if ($.NSFileManager.defaultManager.fileExistsAtPath(f)) {
            /*
             * label index
             *  0 : none
             *  1 : grey
             *  2 : green
             *  3 : purple
             *  4 : blue
             *  5 : yellow
             *  6 : red
             *  7 : orange
             */
            let res = set_label(7, f);
            console.log(res);
        }
    }
}

function set_label(n, fpath) {
    let furl = $.NSURL.fileURLWithPath(fpath);

    let err = $()
    let res = furl.setResourceValueForKeyError(
        n,
        'NSURLLabelNumberKey',
        err
    );

    if (res) {
        return fpath;
    } else {
        return fpath + ': ' + err.localizedDescription.js;
    }
}


2019/05/31 18:24 Hiro__S への返信

ごめんなさい。ちょっと間違えてしまいました。修正版です。


#!/bin/bash

#
# usage: bash me.sh file
#

[[ $# > 0 ]] || { echo "usage: bash $0 file" >&2; exit 1; }

finderinfo=$(xattr -p com.apple.FinderInfo "$1" 2>/dev/null | perl -0pe 's|\s||g')
[[ -n "${finderinfo}" ]] || finderinfo=$(jot -s '' -b 0 64)
echo "FinderInfo : ${finderinfo}"

finderflags=${finderinfo:16:4}
echo "FinderFlags: 0x${finderflags}"

finderflags=$(printf '%016s\n' $(bc <<< "obase=2; ibase=16; ${finderflags}"))
echo "FinderFlags: ${finderflags}"

label=${finderflags:12:3}
echo "Label      : ${label}"

i=$(bc <<< "obase=10; ibase=2; ${label}")

labels=("None" "Gray" "Green" "Purple" "Blue" "Yellow" "Red" "Orange")
echo "LabelName  : ${labels[${i}]}"


2019/05/31 18:02 mNeji への返信

ついでにもう一つ。xattr を使ってラベル名を取得するシェルスクリプト。あとは自力で頑張ってください。


#!/bin/bash

#
# usage: bash me.sh file
#

[[ $# > 0 ]] || { echo "usage: bash $0 file" >&2; exit 1; }

finderinfo=$(xattr -p com.apple.FinderInfo "$1" 2>/dev/null | perl -0pe 's|\s||g')
[[ -n "${finderinfo}" ]] || finderinfo=$(jot -s '' -b 0 64)
echo "FinderInfo : ${finderinfo}"

finderflags=${finderinfo:16:4}
echo "FinderFlags: 0x${finderflags}"

finderflags=$(printf '%016s\n' $(bc <<< "obase=2; ibase=16; ${finderflags}"))
echo "FinderFlags: ${finderflags}"

label=${finderflags:12:3}
echo "Label      : ${label}"

index=$(bc <<< "obase=10; ibase=2; ${label}")
echo "LabelIndex : ${index}"

labels=("None" "Gray" "Green" "Purple" "Blue" "Yellow" "Red" "Orange")
echo "LabelName  : ${labels[${index}]}"


2019/05/31 16:01 mNeji への返信

ラベルを取得する JXA スクリプト


ラベルの取得と設定は Finder 経由でもっと簡単にできますが、タグを取得/設定するスクリプトと似たような感じにしてみました。


//
// usage: osascript -l JavaScript me.applescript file1 file2 ...
//

function run(argv) {
    let argc = argv.length;

    if (argc < 1) {
        return 1;
    }

    for (let f of argv) {
        if ($.NSFileManager.defaultManager.fileExistsAtPath(f)) {
            let res = get_label(f);
            console.log([f, res]);
        }
    }
}

function get_label(fpath) {
    let furl = $.NSURL.fileURLWithPath(fpath);
    let err = $();
    let dct = furl.resourceValuesForKeysError(['NSURLLabelNumberKey'], err);

    if (dct.allKeys.containsObject('NSURLLabelNumberKey')) {
        let index = dct.objectForKey('NSURLLabelNumberKey');

        let labels = {
            0 : 'none',
            1 : 'grey',
            2 : 'green',
            3 : 'purple',
            4 : 'blue',
            5 : 'yellow',
            6 : 'red',
            7 : 'orange',
        };

        let i = ObjC.deepUnwrap(index);

        return labels[i];
    }
}


2019/06/07 03:47 mNeji への返信

最低限やりたいことは

[A] オプション解析 (簡単なもの良い)

[B] オプション解析時の文字列比較 (NFKC Casefold、ひらがな/カタカナを区別しない)

[C] タグの付与 (直接できない場合は osascript 経由で JXA or ASOC)


OS に標準搭載の Python 2.7.10 の場合、[A] は簡単にできます。[C] はPyObjC なら直接できますし、osascript から JXA でも可。


[B] はちょっと面倒で、NFKC は簡単にできますが、casefold は v2系ではかなり難しいと思います。Python 3系であれば ズバリ casefold() があるので、それを使うと良いでしょう。あと、ひらがな/カタカナ変換は PyOjbC ではなぜかできません。JXA ならは普通にできるのですが...。これは NKF を別途用意すると簡単にできるようになります。


ということで、Python 3.3 以上と NKF を別途用意すれば (AppleScript のヘンテコ仕様に頼ることなく) 比較的短いコードで実現可能と思われます。


私は、可能な限り OS に標準搭載のもので組めるものを紹介する...という方針でここ参加してます。ここから先は自力で解決してください。


ーーーーー


あと、詳細は書きませんが、Ruby + JXA も選択肢としては良いと思います。v2.3 でも良いのですが、本件の場合、v2.6 だとさらに簡単にできると思います。(v2.6 は実際試してませんが...)


ーーーーー


さて、スクリプト言語の今後についてですが、時期は不明も Python、Ruby 等は OS に標準搭載されなくなります。


macOS Release Notes

macOS 10.15 Beta Release Notes


なので、来たるべき日に備え、Homebrew を導入するなり、ソースを拾ってきて自分でコンパイルする練習をしておいた方が良いと思います。


では、頑張ってください。


2019/06/01 23:22 mNeji への返信

>「この」をクリックしましたが、それらしいものは在りませんでした。


失礼しました。最初にリンクなしで送信してしまい直後に修正しました。ページをリロードしてください。


↓ちなみにこれです。

https://discussionsjapan.apple.com/thread/250394186?answerId=250759225122#250759225122


2019/06/01 21:53 Hiro__S への返信

iro.Sさん、


夢のなかで、スクリプトからなら、同一色のタグを複数設定できるのではという様に思いました。


取り急ぎ「タグを設定する JXA スクリプト」を「タグを取得する JXA スクリプト」と同様に準備して呼び出しましたが、

三色を別々にすれば設定できましたが、二色同時に設定すると無視されます。


ふと以前の記憶から、ラベルの時はできたと思うので、ラベル設定で試して見ます。もし上手くいけば、ファインダーからの設定は放棄します、...だといいな。


2019/06/04 09:35 hohokihai への返信

hohokihaiさん、


遅ればせながらtagnamesを動かしました。残念なことにtagsの読み込みは成功しましたが、書き込みは失敗しました・


図1 tget(Hiro.S謹製)とtagnames(hohokihai謹製)とによる「tagsの読み込み」は成功。

  


図2 tagnames(hohokihai謹製)による「tagsのクリア(-c)、書き込み(-a)」は失敗。

  



🔷 やはり、当方のFinderの設定不良が不良な可能性が高くなってきました。冷静になって対処を考えます。



追記:

  • Xcodeの操作に慣れてきて、一度ファイル群を消失。
  • 二度入力して、今度は成功。
  • 「Swift for macOS-app」の資料は激レアだ!
  • Horo.SさんのPython版は明日入力の予定です。Pythonの参考書はシンボルが嫌いで全て放棄してしまいました。

2019/05/31 17:43 Hiro__S への返信

Hiro.Sさん、


とても俯瞰的で、迅速なコメント感謝します。


当面は「タグを取得する JXA スクリプト」を動かして、目を馴らしたいと思います。


Finderだけ見ていると、タグだけでラベルなんてなくなったものと理解していました。


「NSURLResourceKey - Foundation | Apple Developer Documentation」も斜め読みしてみます。



段々と、冗談で書いた「CLI型のフィンダーとグーグル検索」などが出来そうな...。



追伸:

  • タグの表示にemojiを使おうと眺めて見ましたが、色・形が揃ったのが無いのでがっかり。
  • 最後にリプライしようとすると、「我慢できないならネイティブな Objective-C なり Swift なりで書き換えて」......

2019/06/01 10:38 mNeji への返信

ところで、「JXA スクリプト」をXcodeで制作・デバックは可能でしょうか?osascriptというのは馴染みにくいです。


Xcode で作成することは可能ですが、デバックまでできるのかは知りません。


osascript に馴染めないなら、Script Editor から実行できるようにコードを書き換えると良いかもしれません。で、console.log() でこまめにログを出力しながら動きを追うと良いでしょう。


それと、デバックについては Safari が使えるようです。個人的には馴染めなかったので数回使ったきりです...。使い方は Google 検索してください。


javascriptは文法的には抵抗感がありませんが、NSナンチャラと仲良しに慣れなそうです泣。


NS ナンチャラの部分は Objective-C ですから、それに抵抗感があるなら全体を Swift で書き直すと良いでしょう。なお、私は Swift の勉強を未だ開始してませんからアドバイスはできません。他の方のコメントを待ってください。


タグの取得と設定は mNeji さんが考えているよりは難しいと思います。頑張ってください。


このスレッドはシステム、またはAppleコミュニティチームによってロックされました。 問題解決の参考になる情報であれば、どの投稿にでも投票いただけます。またコミュニティで他の回答を検索することもできます。

「Finderで付けた複数カラー・タグ」を「Terminalコマンドで如何に処理」すればよいか?

Apple サポートコミュニティへようこそ
Apple ユーザ同士でお使いの製品について助け合うフォーラムです。Apple Account を使ってご参加ください。