PowerShellで正規表現の文字置き換えを使いWindowsのローカルパスをLinuxのパスに変換

PowerShell コンピュータ
PowerShell

正規表現での文字の置き換えは便利なのですが、頻繁に使わないと使い方を忘れてしまいます。

特に特定の文字列をキャプチャし、変換後の文字列にキャプチャした文字を組み入れるケースによく遭遇するので、確認してみたいと思います。

今回はWSLなどで扱うLinuxのパスとWindowsのパスの変換を考えてみたいと思います。

PowerShellの文字の置き換えは正規表現が使えない.Replace()メソッドと、正規表現が使える-replace演算子の2種類があります。以下の例ではWindowsの区切り記号の’\’とLinuxの区切り記号を’/’を.Replace()で置き換えています。
次に-replaceを使いWindowsの’ドライブ名:’を、’/mnt/ドライブ名’という形式に置き換えています。

Windows⇒Linux

'h:\tools'.Replace('\', '/') -replace '^([a-zA-Z]):',"/mnt/`$1"

Linux⇒Windows

('/mnt/h/tools/hoge' -replace '^/mnt/([a-zA-Z]+?)',"`$1:").Replace('/','\')

余り精査せず作ったので、正しく動作しないケースもあるかとは思いますが、一応それらしく動作します。
追記:
動作していると思いましたが、ドライブ名が大文字の場合うまく動作しません。

$profileに組み込む

# =============================================================================
# WindowsのパスをLinuxのパスへ変換
# =============================================================================
Function w2l
{
    Param ([string]$WinodwsPath)
    return [regex]::replace($WinodwsPath, "^\w:", { $args.value.toLower() }).Replace('\', '/') -replace '^([a-zA-Z]):',"/mnt/`$1"
}
# =============================================================================
# LinuxのパスをWindowsのパスへ変換
# =============================================================================
Function l2w
{
    Param ([string]$LinuxPath)
    return ($LinuxPath -replace '^/mnt/([a-zA-Z]+?)',"`$1:").Replace('/','\')
}

w2lだけドライブ名を大文字から小文字へ変換するルーチンを加えました。最初にPowerShellでは文字の置き換えが2種類あると述べましたが、今回追加した方法は.NetのRegexクラスを使い置き換えをしています。replace演算子では正規表現でキャプチャした文字をそのまま使うしかできませんが、Regexではキャプチャした文字を加工(今回は小文字に置き換え)することが出来ます。

実行例

PS C:\Users> w2l 'h:\hoo\bar'
/mnt/h/hoo/bar
PS C:\Users> l2w '/mnt/h/hoo/bar'
h:\hoo\bar
PS C:\Users> l2w(w2l 'h:\hoo\bar')
h:\hoo\bar

PowerShellでパスの置き換えのスクリプトを書いてはみましたが、実際WSL環境であればwslpathが使えますので其方を使いましょう。

WSL内で実行

Windows⇒Linxu
wslpath windowsのパス

Linux⇒Windows
wslpath -w ubuntuのパス

ちなみにPowerShellから呼び出す場合は、wslpathの前にwslスペースをセットします。

コメント