在Bash中将Windows路径转换为posix路径

70

如何使用标准 msys 功能将 Windows 目录路径(例如 c:/libs/Qt-static)转换为正确的 POSIX 目录路径(/c/libs/Qt-static)?反之亦然。

9个回答

74
Cygwin、Git Bash 和 MSYS2 均提供了一个名为 cygpath.exe 的实用工具,专门用于此目的。
输出类型选项: -d, --dos 打印 NAMEs 的 DOS(短)形式(C:\PROGRA~1\) -m, --mixed 类似于 --windows,但使用常规斜杠(C:/WINNT) -M, --mode 报告文件的模式(binmode 或 textmode) -u, --unix (默认)打印 NAMEs 的 Unix 形式(/cygdrive/c/winnt) -w, --windows 打印 NAMEs 的 Windows 形式(C:\WINNT) -t, --type TYPE 打印 TYPE 形式:'dos'、'mixed'、'unix' 或 'windows'

1
请查看此邮件:http://sourceforge.net/mailarchive/message.php?msg_id=8686481 - anishsane
谁曾经对这个答案点了踩,请也留下评论指出任何错误,这样我就可以改正... :-) - anishsane
5
cygpath似乎在MINGW64(git bash)上可以使用。不确定是因为我也安装了cygwin,还是因为自从这个问题被提出后已经添加到系统中了 - 但我能够从cygpath 'd:\something'得到预期的结果 - 它如何自动将来自剪贴板或自定义环境变量的字符串翻译? - hood
当实用程序不支持从标准输入时,pwd | cygpath -w -- 优于 cygpath -w $(pwd)。这真是太烦人了<sigh/>。 - JJS
3
安装git-bash时会自带cygpath.exe。你无需安装cygwin或了解cygwin是什么。在使用git-bash时,cygpath.exe已被添加到路径中。 - ZYinMD
显示剩余6条评论

53

我不了解 msys,但是快速的谷歌搜索显示它包含了 sed 工具。所以,假设在 msys 中它的使用方式与本地 Linux 相似,这里有一种方法可以实现:

从 Windows 到 POSIX

你需要用斜杠替换所有反斜杠,删除驱动器字母后面的第一个冒号,并在开头添加一个斜杠:

echo "/$pth" | sed 's/\\/\//g' | sed 's/://'

正如xaizek所指出的那样,

echo "/$pth" | sed -e 's/\\/\//g' -e 's/://'

从 POSIX 到 Windows

您需要添加一个分号,移除第一个斜杠并将所有斜杠替换为反斜杠:

echo "$pth" | sed 's/^\///' | sed 's/\//\\/g' | sed 's/^./\0:/'

或者更高效地说,

echo "$pth" | sed -e 's/^\///' -e 's/\//\\/g' -e 's/^./\0:/'

其中$pth是分别存储Windows或POSIX路径的变量。


2
@Dukales:为什么?据我所知,没有前导斜杠表示相对路径,而前导斜杠使其成为文件系统根的绝对路径。 - Rody Oldenhuis
11
你知道,没有必要使用多个sed调用,只需将多个-e command参数传递给单个实例即可(例如sed -e one -e two)。 - xaizek
2
当使用随 Git 一起提供的 Bash 时,驱动器字母需要小写,并且某些文件夹名称可能以“$”开头-请尝试以下操作: echo "$pth" | sed -e 's#\\#/#g' -e 's#\$#/\\$#g' -e 's#^\([a-zA-Z]\):#/\L\1# - Francois
2
当将Windows中具有多个路径的字符串转换为POSIX时,必须在每个路径前添加一个前导/。更有效的命令版本将变为:echo "$pth" | sed -e 's/\\/\//g' -e 's/\([a-zA-Z]\):/\/\1/g' - Klamer Schutte
2
在Git Bash中(至少是这样;我不知道Cygwin或其他Windows中的POSIX兼容shell如何处理Windows路径),路径前缀X:(其中X是驱动器字母)变成了/x,因此sed 's/://'应该改为sed -r 's|^([^:]+):|\/\L\1|'(至少在Git Bash中使用时;我还自作主张将/更改为|,因为我个人认为在sed脚本中这样做会更清晰易懂)。 - HelloGoodbye
显示剩余6条评论

25

只需使用cygpath

$ cygpath -w "/c/foo/bar"
 -> C:\foo\bar

$ cygpath -u "C:\foo\bar"
 -> /c/foo/bar

你可能会想:“我是否已经安装了cygpath?”好吧,
  1. 如果你在git-bash中,那么是的。
  2. 如果你在cygwin或MSYS2中,那么是的。
  3. 如果你在另一个shell中,但之前已经安装了git-bash,那么cygpath可以在git-bash-install-folder\usr\bin\cygpath.exe找到。
  4. 否则:也许没有,但我相信你可以找到一种方法来安装它。

9
在MSYS中,"正确"的方法是:
$ MSYS_NO_PATHCONV=1  taskkill /F /T /IM ssh-agent.exe

这样可以避免手动翻译斜杠。它只是取消路径转换。

4

以下是我的实现(在Git Bash上测试通过)。

从POSIX到Windows

sed '
    \,/$, !s,$,/,
    \,^/, s,/,:/,2
    s,^/,,
    s,/,\\,g
    ' <<< "$@"

适用于:

/c/git
relative/dir
c:/git
~
.
..
/c
/c/
./relative/dir
/sd0/some/dir/

除了

/
<path with space>

解释:

\,^/,s,/,:/,2(将/drive/dir/转换为/drive:/dir/)是其核心,它在第二个/之前插入:。我使用,作为分隔符,而不是/以便阅读。如果以/开头(\,^/,),则用:/替换第二个出现的/。我不想假设驱动器字母长度为1,因此这适用于/sd0/some/dir

s,^/,,去除前导的/s,/,\\,g将所有/转换为\\

\,/$,! s,$,/,用于处理/c的特殊情况,并确保下一个命令的第二个//c/)起作用。

注意:

如果在您的shell中无法使用此处字符串<<<,则可以使用echo和管道。

echo "$@" | sed ...

Errata

Here e script


4

提供信息 - 至少对于我的git版本2.26.2.windows.1而言, 例如,如果我有一个路径,如C:\ dev \ work_setup \ msk,我可以直接进入Git Bash并输入

cd "C:\dev\work_setup\msk"

这将导致当前文件夹更改为/c/dev/work_setup/msk - 因此,只要我将Windows路径放在双引号内,这种类型的转换似乎是自动完成的。不幸的是,我没有参考原始文档来支持这一点。


这对我起作用了,而“cygpath --unix”没有,它返回路径减去任何斜杠。 - Pellet

1

@hello_earth的回答是误导性的,因为Windows路径必须使用双反斜杠,例如:

cd "e:\\dir\\subdir\\path"

否则,Shell将会找到转义序列。

1
我的解决方案适用于一个文件夹/文件列表,并分为两个步骤。 假设您想将Windows路径从 D:\example 更改为/ example,并替换该路径在此文件列表中的所有重复项。
第一步是将反斜杠更改为斜杠。
grep -lr "D:\\\\example" /parent-folder | xargs -d'\n' sed -i 's+\\+\/+g'

请注意,parent-folder 可以是根目录 (/) 或您喜欢的任何其他目录,并且如果文件名或文件夹名称中包含空格,则需要使用 -d'\n' 参数。

第二步将 D:/example 替换为 /example:

grep -lr "D:/example" /parent-folder | xargs -d'\n' sed -i 's+D:+/example+g'

我想分享这个解决方案,因为我花了一些时间来编写这两行代码,但它真的是非常有用的工作(我正在将一个Windows应用程序迁移到一个充满Windows路径的Linux服务器上)。


0

我认为这可以帮助你。我为自己做了这个。

这将把所有Windows路径转换为POSIX路径:

https://github.com/hypolas/wintobashpath

技术:

  • 将Windows驱动器字母转换为小写
  • 从反斜杠改为正斜杠
  • 在路径开头添加斜杠
  • 创建一个~/.bashrc.d/目录
  • 创建一个文件~/.bashrc.d/winToBashPath.bashrc
  • 将转换后的PATH添加到~/.bashrc.d/winToBashPath.bashrc中
  • 添加以下行以保持~/.bashrc干净:
for the file in ~/.bashrc.d/*.bashrc;
do
    . "$file"
done

我的结果:

echo %PATH%
C:\Program Files (x86)\Common Files\Oracle\Java\javapath;C:\Windows\system32;C:\Windows;C:\Windows\System32\Wbem;C:\Windows\System32\WindowsPowerShell\v1.0\;C:\Windows\System32\OpenSSH\;C:\Program Files\dotnet\;C:\Program Files (x86)\NVIDIA Corporation\PhysX\Common;C:\Program Files\PowerShell\7\;C:\Program Files\nodejs;;E:\Program Files\Git\cmd;C:\Program Files\Go\bin;C:\Users\hypolas\AppData\Local\Microsoft\WindowsApps;C:\Users\hypolas\AppData\Local\Programs\Microsoft VS Code\bin;E:\msys64-2023\mingw64\bin;C:\Users\hypolas\AppData\Roaming\npm;C:\Users\hypolas\go\bin

变成了:

echo $PATH
/mingw64/bin:/usr/bin:/c/Users/hypolas/bin:/c/Users/hypolas/bin:/mingw64/bin:/usr/local/bin:/usr/bin:/usr/bin:/mingw64/bin:/usr/bin:/c/Users/hypolas/bin:/c/Program Files (x86)/Common Files/Oracle/Java/javapath:/c/Windows/system32:/c/Windows:/c/Windows/System32/Wbem:/c/Windows/System32/WindowsPowerShell/v1.0:/c/Windows/System32/OpenSSH:/c/Program Files/dotnet:/c/Program Files (x86)/NVIDIA Corporation/PhysX/Common:/c/Program Files/PowerShell/7:/c/Program Files/nodejs

您可以将此二进制文件放置在Windows启动文件夹中,这样如果您安装带有PATH的新软件,则该PATH将自动添加到启动时的bashrc。

如果您有任何建议,我可以为您更新此内容,以帮助更多的人。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接