WindowsとMacで同じ共有フォルダーを案内する場合は、UNCパスとSMB URLの書き方を変換できます。
ローカルのCドライブや、Macの/Volumes以下の名前だけから共有サーバーを推測する処理とは分けて扱います。
変換できる共有パスと入力例
| 入力 | 処理の条件 | 期待する結果 |
|---|---|---|
| Windows共有パス | \\files.example.invalid\team\file.txt | smb://files.example.invalid/team/file.txt |
| 日本語と空白 | 共有名と各ファイル名を個別にURLエンコード | SMBから戻すと元の文字列に一致 |
| C:\local\file.txt | 共有サーバーの情報がない | 変換せずエラー |
| /Volumes/制作共有/file.txt | 接続元のサーバー・共有名が必要 | 本コードの対象外 |
例のexample.invalidは架空のサーバー名です。
今回の処理は文字列だけを変換し、サーバーへの接続・認証・ファイル操作を行いません。
空白と日本語を保持するPythonコード
練習ZIPのshared_path.pyはPython 3.10以上の標準ライブラリーだけを使います。
URL全体を単純に置換せず、共有名と各項目を個別にエンコードします。
"""Convert explicit UNC/SMB strings only. No network, mount lookup or clipboard."""
import argparse
import re
from urllib.parse import quote, unquote, urlsplit
def host_ok(host):
if not re.fullmatch(r"[A-Za-z0-9](?:[A-Za-z0-9.-]*[A-Za-z0-9])?", host):
raise ValueError("Use a plain server hostname; credentials/ports are unsupported.")
return host
def segments_ok(parts):
if not parts or any(not p or p in (".", "..") or
any(c in p for c in '\\/:*?"<>|') or
any(ord(c) < 32 for c in p) or p.endswith((" ", "."))
for p in parts):
raise ValueError("Invalid share/path component.")
return parts
def unc_to_smb(value):
if not value.startswith("\\\\"):
raise ValueError("Expected \\\\server\\share path, not a local drive.")
host, *parts = value[2:].split("\\")
parts = segments_ok(parts)
return "smb://" + host_ok(host) + "/" + "/".join(quote(p, safe="") for p in parts)
def smb_to_unc(value):
if any(ord(c) < 32 for c in value):
raise ValueError("Control characters are unsupported.")
u = urlsplit(value)
if u.scheme != "smb" or u.query or u.fragment or not u.netloc:
raise ValueError("Expected smb://server/share URL without query/fragment.")
host = host_ok(u.netloc)
encoded = u.path[1:].split("/") if u.path.startswith("/") else []
if any(re.search(r"%(?![0-9A-Fa-f]{2})", p) for p in encoded):
raise ValueError("Malformed percent escape.")
parts = segments_ok([unquote(p, encoding="utf-8", errors="strict") for p in encoded])
return "\\\\" + host + "\\" + "\\".join(parts)
if __name__ == "__main__":
parser = argparse.ArgumentParser(description=__doc__)
parser.add_argument("direction", choices=["unc-to-smb", "smb-to-unc"])
parser.add_argument("paths", nargs="+")
args = parser.parse_args()
convert = unc_to_smb if args.direction == "unc-to-smb" else smb_to_unc
try:
results = [convert(p) for p in args.paths]
except (ValueError, UnicodeError) as error:
parser.error(str(error))
print("\n".join(results))
PowerShellでpython shared_path.py unc-to-smb '\\files.example.invalid\制作共有\企画 A.txt'を実行すると、空白を%20、日本語をUTF-8のURL表記にしたSMB URLが出ます。
その結果をpython shared_path.py smb-to-unc '変換したSMB URL'に渡すと元のUNCへ戻ります。

Automatorに渡す前に決めること
Macでクイックアクションへ組み込む場合は、入力をテキストに限定し、「シェルスクリプトを実行」の入力を引数として受け渡します。
Pythonの実行ファイルとshared_path.pyの絶対パスを確認し、入力ごとに二重引用符で囲んで渡します。
unc-to-smbとsmb-to-uncは別の処理なので、アクションを分けてから最後に「クリップボードにコピー」を配置します。
Finderで選んだ/Volumes以下のファイルを自動で共有パスへ戻すワークフローは、このコードには含めません。
AppleのAutomatorでスクリプトを使う手順は、保存前にワークフローを試すよう案内しています。
Macの入力・コピー・クイックアクション実行は今回未検証のため、完成した.workflowは配布していません。
変換できないときの切り分けと戻し方
サーバーと共有名がないパス、ユーザー名やポートを含むURL、クエリー・フラグメント、不正な%表記、区切りを含むエンコードはエラーにします。
エラーが出ても入力やクリップボードを変更せず、正しい共有パスか確認してください。
末尾の区切り、IPv6形式のホスト、相対パスやローカルドライブも本コードでは扱いません。
共有パスへ変換できても、実際に相手が接続できるかどうかは権限と接続先で別に確認する必要があります。
確認済みなのは、日本語・空白・%・#を含むPythonの相互変換と、不正な入力の拒否です。
元の文字列を手元に残し、作成したアクションを使わない状態へ戻せば、共有サーバーの設定を戻す作業はありません。
URL処理はPython公式のurllib.parseを参照してください。
最終確認:2026年10月3日。
関連するファイル操作の記事
| やりたいこと | 最初に読む記事 |
|---|---|
| SSDが一覧に出ない | 接続の4段階を確認 |
| 名前が見つからない | 削除前の名前照合 |
| ZIPを展開する | 出力先と同名ファイルを確認 |
| フォルダーをまとめる | CFUと設定の戻し方 |
ファイル操作の関連記事と旧コードの区別
関連記事やGitHubの旧コードは、本稿の練習ZIPと異なる場合があります。
今回の確認には本稿のZIPと入力例を使ってください。









