转换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

Answers:


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

您可以wslpath在Windows上从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,请访问以下网址
好战的黑猩猩

1
豪华的需要转义'\',但wsl不需要。您的示例$ wslpath -a 'C:\\aaa\\bbb\\ccc\\foo.zip'应为:$ wslpath -a 'C:\aaa\bbb\ccc\foo.zip'逃脱时有效,但无用的转义令人困惑。一个人可以假设它必须被逃脱。另外,我觉得就说明-m... with ‘/’ instead of ‘\\’应该有一个“\”(我知道它的复制粘贴),如果你这样做wslpath -w /mnt/c/Users,它不会打印两个“\\”
PAPO

1
我相信这wslpath是答案的一部分,但是我相信这篇文章在功能上不能回答这个问题-当批处理文件具有C:\foo\bar\blah数据文件的Windows样式()名称时,它如何在WSL命令上运行该文件?
斯科特

@papo我刚刚偶然发现了usescapeed斜杠的问题:它是不一致的,并取决于它的运行方式;从powershell运行时,它会省略未转义的斜杠;从bash运行时,它仅在字符串内部正确对待它们。
Sukhmel

@sukhmel是真的,在wsl(运行Windows的bash程序)以及cmd控制台中,可以将路径放在单引号或双引号中,或者以\\进行转义。不必在引号内转义,这是一种快速的方法:cat `wslpath '然后将文件进入控制台并完成操作:'`
papo

5

我写了一个蝙蝠文件来做到这一点。只需将文件放在您正在使用的任何地方,或将其添加到路径中(或将其放在代码上方即可,这样更容易使用)。请记住,首先要为文件路径分配“变量”(如果使用单独的文件,请尝试使用参数)。

代码的作用是:

1)获取路径的第一个字母,即驱动器。

2)删除前两个字母。

3)更改斜线。

4)这是棘手的部分:由于Linux区分大小写,因此我们需要将大写驱动器号转换为小写。通过匹配每个对象(如果有更好的方法告诉我)来做到这一点。您也可以删除不必要的驱动器号,因为您可能不超过十个驱动器。

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

反过来,在shell脚本中将Unix路径转换为Windows路径呢?
JacobTheDev '17

@JacobTheDev,您只需要对此稍作修改;)
PulseJet


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')?
斯科特
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.