Help us understand the problem. What is going on with this article?

macOSからWindowsへのパス変換でハマった所とその解決法

グレンジ Advent Calendar 2018 6日目担当の soyo と申します。
グレンジでcocos2d-xによるゲーム開発のクライアントエンジニアをしております。

とはいえ、今回の記事はcocos2d-xとはまったく関係ありません。
簡単そうなパス変換ですが、意外と躓いてしまったので、その解決方法をまとめたいと思います。
(日本語が拙いところがありますが、ご容赦ください)

技術・環境

  • macOS
  • Automator
  • AppleScript
  • JavaScript

やりたいと思ったきっかけ

最初は、macOSのパスをWindowsのパスに変換して共有したいだけでしたが、
その時に、一つ問題が発生しました。

どういう問題かというと、
いつもの手順は、まず共有サーバーに置いてあるファイルの詳細情報からパスをコピーします。
2.png
そして、ネットのパス変換ツールで変換して、
チャットワークで共有すれば、これで大丈夫かなと思いました。
4.png
が、アクセスできないだと?!
4.5.png
これは困るので、この際は自作してみようと思います!

発生した問題

濁点問題

送ったリンクをテキストエディターに貼ると、なぜか濁点がずれているようです。
5.png
ネットで調べると、Macでファイル名をコピペすると濁点と半濁点がおかしくなるという記事がありました。
この記事によると、macOSの自動化ツールAutomatorでシェルを実行すれば解決できそうですね!

マウント先のパス問題

結果、Automatorでシェル実行してコピーされたパスは以下のものとなりました…
volumes.png
これで、マウント先のパスが簡単に取れないことがわかりました。
でも、一応エンジニアである私がこんなところでやられてたまるか!

マウント先のパスを見る方法なら知っていますよ!

$ mount | grep "[デバイス名]"

これでマウント先のパスを見れます!
7.png
そして、AutomatorはAppleScriptというスクリプト言語が使えますので、
ネットで見つけたパスを変換するコードで、一応動きました!

と思ったら、なんと次の問題が発生してしまいました…
14.png

UTF-8問題

上記のエラーについて調べた結果、
マウント先のパスがUTF-8文字が存在する場合のみエラーが出ます。

例:
12.png
この場合は

$ mount | grep "[デバイス名]"

を実行すると
8.png
なんとパーセントエンコーディング?!
しかも後ろの部分(onから)は漢字のままになっています!

そのまま化けた文字が使えると思うのか!
10.png
......
11.png
使えますね。

わかったわかった、自分もこういう風に対応すれば良いでしょう。

実はAutomatorではJavaScriptも使えそうです。
script.png
JavaScriptではdecodeURIという関数が存在して、デコードができそうです。
さらに、normalize('NFC')という関数で濁点の問題も解決できそうです。

function run(input, parameters) {
    return decodeURI(input).normalize('NFC');
}

これで、やっと正しい変換ができるようになりました。
13.png
ファイルの右クリックメニューからワンクリックでWindowsのパスをコピーすることができます。
15.png

もちろん、複数ファイルのパスも変換できます。
16.png
17.png

最終的に実装できたもの

Automator設定

auto.png
setting.png

AppleScriptコード(smbのみ対応、afpはまだ)

on splitString(str, delimiter)
    set OldDelims to AppleScript's text item delimiters
    set AppleScript's text item delimiters to delimiter
    set stringList to every text item of str
    set AppleScript's text item delimiters to OldDelims
    return stringList
end splitString

on getRealPath(input_file_path)
    set smbPrefix to "/Volumes/"
    if input_file_path starts with smbPrefix then
        set file_path to text items 2 thru -1 of splitString(input_file_path, smbPrefix) as string
        set mount_name to text item 1 of splitString(file_path, "/") as string
        set shell_command to "mount | grep \" on " & smbPrefix & mount_name & "\""
        set mount_path to do shell script shell_command
        set mount_path to text items 2 thru -1 of splitString(mount_path, "@") as string
        set mount_path to text item 1 of splitString(mount_path, " on /Volumes") as string
        set file_path to text items 2 thru -1 of splitString(file_path, mount_name & "/") as string
        return "smb://" & mount_path & "/" & file_path
    end if
    return input_file_path
end getRealPath

on searchReplace(theText, SearchString, ReplaceString)
    set OldDelims to AppleScript's text item delimiters
    set AppleScript's text item delimiters to SearchString
    set newText to text items of theText
    set AppleScript's text item delimiters to ReplaceString
    set newText to newText as text
    set AppleScript's text item delimiters to OldDelims
    return newText
end searchReplace

on toWindowsPath(file_path)
    set win_path to file_path
    set win_path to searchReplace(win_path, "<", "")
    set win_path to searchReplace(win_path, ">.", "")
    set win_path to searchReplace(win_path, ">", "")
    set win_path to searchReplace(win_path, "smb://", "\\\\")
    set win_path to searchReplace(win_path, "/", "\\")
    return win_path
end toWindowsPath

on run {input, parameters}
    set results to ""
    repeat with input_file in input
        set real_path to getRealPath(the POSIX path of input_file)
        if real_path starts with "smb://" then
            set results to results & toWindowsPath(real_path) & return
        else
            display dialog "ローカルパスをWindows用パスに変換できません" buttons {"OK"} default button "OK"
            return ""
        end if
    end repeat
    return results
end run

まとめ

Finderの詳細情報から見せるmacOS詳細パスはこんなに複雑だとは思いませんでした。

ただ、濁点・マウント先のパス取得・UTF-8問題といういろんな山をこえた結果、
ワンクリックでパス変換できるようなものができて嬉しかったです。

ちなみに、社内で何人かに使ってもらった結果、結構好評でした。

Why do not you register as a user and use Qiita more conveniently?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
Comments
Sign up for free and join this conversation.
If you already have a Qiita account
Why do not you register as a user and use Qiita more conveniently?
You need to log in to use this function. Qiita can be used more conveniently after logging in.
You seem to be reading articles frequently this month. Qiita can be used more conveniently after logging in.
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away