如何通过标准 msys 功能将
Windows目录路径(例如
c:/libs/Qt-static
)转换为正确的 POSIX目录路径(
/c/libs/Qt-static
)?反之亦然?
Cygwin、Git Bash 和 MSYS2 有一个名为
cygpath.exe
的现成实用程序就是为了这样做。
输出类型选项: -d, --dos 打印名称的 DOS(短)形式(C:\PROGRA~1\) -m, --mixed 类似于 --windows,但带有正斜杠 (C:/WINNT) -M, --mode 报告文件模式(binmode 或 textmode) -u, --unix(默认)打印名称的 Unix 形式(/cygdrive/c/winnt) -w, --windows 打印 Windows 形式的名称 (C:\WINNT) -t, --type TYPE 打印 TYPE 形式:'dos'、'mixed'、'unix' 或 'windows'
我不知道
msys
,但谷歌快速搜索显示它包含sed
实用程序。因此,假设它在 msys
中的工作方式与在本机 Linux 中的工作方式相似,这是一种方法:
您必须将所有反斜杠替换为斜杠,删除驱动器号后的第一个冒号,并在开头添加斜杠:
echo "/$pth" | sed 's/\\/\//g' | sed 's/://'
或者,如 xaizek 所述,
echo "/$pth" | sed -e 's/\\/\//g' -e 's/://'
您必须添加一个分号,删除第一个斜杠并将所有斜杠替换为反斜杠:
echo "$pth" | sed 's/^\///' | sed 's/\//\\/g' | sed 's/^./\0:/'
或更有效,
echo "$pth" | sed -e 's/^\///' -e 's/\//\\/g' -e 's/^./\0:/'
其中
$pth
是分别存储 Windows 或 POSIX 路径的变量。
只需使用
cygpath
:
$ cygpath -w "/c/foo/bar"
-> C:\foo\bar
$ cygpath -u "C:\foo\bar"
-> /c/foo/bar
你可能会想:“我安装了
cygpath
吗?”嗯,
cygpath
可以在git-bash-install-folder\usr\bin\cygpath.exe
找到。MSYS中“正确”的方式是:
$ MSYS_NO_PATHCONV=1 taskkill /F /T /IM ssh-agent.exe
这避免了手动翻译斜杠。它只是停用路径转换。
这是我的实现(在 git bash 上测试)。
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/
)是它的核心,并在 :
和 2
之前插入 /
。我使用 ,
代替 /
来提高可读性。如果以 /
(\,^/,
) 开头,则将 /
替换为 :/
对于第 2
次出现。我不想假设驱动器号长度为 1,所以这适用于/sd0/some/dir
.
s,^/,,
删除前导 /
和 s,/,\\,g
将所有 /
转换为 \
.
\,/$, !s,$,/,
是处理 /c
的极端情况,并确保第二个 /
(/c/
) 为下一个命令工作。
注:
如果这里的字符串
<<<
在您的 shell 中不起作用,那么您可以 echo
和管道作为
echo "$@" | sed ...
勘误表
这里脚本
仅供参考 - 至少对于我的 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 路径放在双引号内即可。不幸的是,我没有参考原始文档来支持它。
我的解决方案使用文件夹/文件列表,分两步完成。 假设您想将路径从 D: xample 替换为 /example 以获取已重复此 Windows 路径的文件列表。
第一步它把反斜线变成斜线
grep -lr "D:\\\\example" /parent-folder | xargs -d'\n' sed -i 's+\\+\/+g'
注意 parent-folder 可以是 root (/) 或任何你喜欢的和 -d' ' 如果您的文件名或文件夹名称带有空格,则需要参数。
第二步将 D:/example 替换为 /example:
grep -lr "D:/example" /parent-folder | xargs -d'\n' sed -i 's+D:+/example+g'
我想分享这个解决方案,因为我花了一些时间来制作这两行,但它确实很有帮助(我正在将 Windows 应用程序迁移到内部有大量 Windows 路径的 Linux 服务器)。
@hello_earth 的回答具有误导性,因为 Windows 路径必须是双反斜杠,例如:
cd "e:\\dir\\subdir\\path"
否则 shell 会找到转义序列。