Windows Ubuntu Bash用のWindowsパスの変換


31

Windows Ubuntu Bashを使用するWindowsバッチスクリプトがあります。引数としてWindowsのフルパスを受け取り、Ubuntu Bashのコマンドにそのパスを渡します。

@echo off
bash -lic 'ffmpeg -i "%1" output.avi'

以下"%1"に、Windowsの完全なパスを示します。"C:\some path\file.avi"

コマンドはエラーを与えます:

C:some pathfile.avi: Protocol not found

このWindowsパスを/mnt/c/some\ path/file.aviWindows Bashが実際に理解するようなパスに変換するにはどうすればよいですか?


必要なのは、すべての出現C:/mnt/c(潜在的に他のドライブ文字にも)置き換えることですよね?
kleinfreund

回答:


41

Windows Build 17046 [1]にwslpath、WSL / Windowsとの間でパスを変換できる新しいユーティリティが含まれています。これは、WSL機能がないことでした。[2]

使用例:

$ echo $0
/bin/bash

$ which wslpath
/bin/wslpath

$ wslpath -a 'C:\\aaa\\bbb\\ccc\\foo.zip'
/mnt/c/aaa/bbb/ccc/foo.zip

wslpathWindowsのPowershellから呼び出すことができます。

>>> wsl wslpath -a 'C:\\aaa\\bbb\\ccc\\foo.zip'
/mnt/c/aaa/bbb/ccc/foo.zip

wslpath オプションとパラメーター:

-a    force result to absolute path format
-u    translate from a Windows path to a WSL path (default)
-w    translate from a WSL path to a Windows path
-m    translate from a WSL path to a Windows path, with ‘/’ instead of ‘\\’

1
古いWindowsの場合は、こちらから入手できます:github.com/laurent22/wslpath
Warlike Chimpanzee

1
poshは '\'をエスケープする必要がありますが、wslはエスケープしません。あなたの例$ wslpath -a 'C:\\aaa\\bbb\\ccc\\foo.zip'$ wslpath -a 'C:\aaa\bbb\ccc\foo.zip'それがエスケープされたときに動作するはずですが、無駄なエスケープは混乱を招きます。エスケープする必要があると想定できます。また、私は思うの説明-m... with ‘/’ instead of ‘\\’「\」1を持っている必要があります(私が知っているそれのコピー&ペースト)そうした場合wslpath -w /mnt/c/Users、それは「\\」は、2つを印刷していません
papo

1
私はそれwslpathが答えの一部であると信じていますが、この投稿は機能的に質問に答えていないと信じていC:\foo\bar\blahます。そのファイル?
スコット

@papo usescapedスラッシュの問題につまずいたばかりです:一貫性がなく、実行方法に依存します。powershellから実行する場合はエスケープされていないスラッシュを省略します。bashから実行する場合は文字列内でのみ正しく処理します。
スクメル

@sukhmel、真(Windowsの実行のためにどのbashの上)WSLでもCMDコンソールで、いずれかのプット・パス単一または二重引用符で、あるいは引用符の提供の内側に行うための高速な方法を逃れるのunneccesity \\としてエスケープ:cat `wslpath 'その後、ドラッグ&ドロップコンソールにファイルと行を完了:'`
papo

5

これを行うために、batファイルを作成しました。作業している場所にファイルを配置するか、パスに追加するだけです(または、コードの上に配置するだけで作業しやすくなります)。最初にファイルパスに「変数」を割り当てることを忘れないでください(別のファイルを使用している場合は、パラメーターを使用してみてください)。

コードの機能:

1)ドライブの最初の文字を取得します。

2)最初の2文字を削除します。

3)スラッシュを変更します。

4)これは難しい部分です。Linuxでは大文字と小文字が区別されるため、大文字のドライブ文字を小文字に変換する必要があります。それぞれを一致させてこれを行います(より良い方法があれば教えてください)。おそらく10台以下のドライブがあるため、不要なドライブ文字も削除できます。

5)すべてを組み合わせて、最終的なストリングを作成します。

結果:

入力:

E:\myfiles\app1\data\file.csv

出力(引用符付き):

"/mnt/e/myfiles/app1/data/file.csv"

コードは次のとおりです。

@echo OFF

set "variable=E:\myfiles\app1\data\file.csv"

set "drive=%variable:~0,1%"

set variable=%variable:~2%
set "variable=%variable:\=/%"

if %drive%==A set "drive=a"
if %drive%==B set "drive=b"
if %drive%==C set "drive=c"
if %drive%==D set "drive=d"
if %drive%==E set "drive=e"
if %drive%==F set "drive=f"
if %drive%==G set "drive=g"
if %drive%==H set "drive=h"
if %drive%==I set "drive=i"
if %drive%==J set "drive=j"
if %drive%==K set "drive=k"
if %drive%==L set "drive=l"
if %drive%==M set "drive=m"
if %drive%==N set "drive=n"
if %drive%==O set "drive=o"
if %drive%==P set "drive=p"
if %drive%==Q set "drive=q"
if %drive%==R set "drive=r"
if %drive%==S set "drive=s"
if %drive%==T set "drive=t"
if %drive%==U set "drive=u"
if %drive%==V set "drive=v"
if %drive%==W set "drive=w"
if %drive%==X set "drive=x"
if %drive%==Y set "drive=y"
if %drive%==Z set "drive=z"

set "variable=/mnt/%drive%%variable%"

echo "%variable%"

@echo ON

シェルスクリプトでUnixパスをWindowsパスに変換する逆についてはどうですか?
-JacobTheDev

@JacobTheDev、あなたはそれのためにわずかな修正が必要です;)
PulseJet

今朝、実際にそれを理解しました!gist.github.com/JacobDB/e71e22c3663175b2369211aeb54362fe
JacobTheDev

0

なぜそんなに複雑なのですか?

レジストリエントリを変更する

HKEY_CLASSES_ROOT\Applications\bash.exe\shell\open\command

から

C:\Windows\System32\wsl.exe "%1"

C:\Windows\System32\wsl.exe `wslpath '%1'`

wslpathの前と末尾にバックティックを使用し、%1の前後に単一引用符(直線の目盛り)を使用します。

私のために働く。


本当に?これbashにより、バッチファイルからどこが呼び出されるかという質問の問題が解決しますか?(この例では、bashの最初の引数は-licであるため、どのように機能するかwslpath '%1'は明確ではありません。)そして、なぜ二重引用符("%1")から単一引用符('%1')に変更したのですか?
スコット
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.