Windows PATH to posix path conversion in bash

WindowsStringBashPathMsys

Windows Problem Overview


How can I convert a Windows dir path (say c:/libs/Qt-static) to the correct POSIX dir path (/c/libs/Qt-static) by means of standard msys features? And vice versa?

Windows Solutions


Solution 1 - Windows

Cygwin, Git Bash, and MSYS2 have a readymade utility called cygpath.exe just for doing that.

Output type options:
-d, --dos             print DOS (short) form of NAMEs (C:\PROGRA~1)
-m, --mixed           like --windows, but with regular slashes (C:/WINNT)
-M, --mode            report on mode of file (binmode or textmode)
-u, --unix            (default) print Unix form of NAMEs (/cygdrive/c/winnt)
-w, --windows         print Windows form of NAMEs (C:\WINNT)
-t, --type TYPE       print TYPE form: 'dos', 'mixed', 'unix', or 'windows'

Solution 2 - Windows

I don't know msys, but a quick google search showed me that it includes the sed utility. So, assuming it works similar in msys than it does on native Linux, here's one way how to do it:

From Windows to POSIX

You'll have to replace all backslashes with slashes, remove the first colon after the drive letter, and add a slash at the beginning:

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

or, as noted by xaizek,

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

From POSIX to Windows

You'll have to add a semi-colon, remove the first slash and replace all slashes with backslashes:

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

or more efficiently,

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

where $pth is a variable storing the Windows or POSIX path, respectively.

Solution 3 - Windows

Just use cygpath:

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

You may wonder: "Do I have cygpath installed?" Well,

  1. If you're using the git-bash shell, then yes.
  2. If you're in cygwin or MSYS2, then yes.
  3. If you're in another shell, but you have installed git-bash before, then cygpath can be found at git-bash-install-folder\usr\bin\cygpath.exe.
  4. Else: maybe not, but I'm sure you can find a way to installed it.

Solution 4 - Windows

The "correct" way in MSYS is:

$ MSYS_NO_PATHCONV=1  taskkill /F /T /IM ssh-agent.exe

This avoids having to manually translate slashes. It simply de-activates the path conversion.

Solution 5 - Windows

Here is my implementation (tested on git bash).

From POSIX to Windows

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

Works for:

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

except

/
<path with space>

Explanation:

\,^/, s,/,:/,2 (converts /drive/dir/ to /drive:/dir/) is the heart of it and inserts : before the 2nd /. I use , for delim instead of / for readability. If starting with / (\,^/,), then replace / with :/ for the 2nd occurrence. I do not want to assume drive letter length of 1 so this works for /sd0/some/dir.

s,^/,, removes the leading / and s,/,\\,g converts all / to \.

\,/$, !s,$,/, is to handle the corner case of /c and ensure 2nd / (/c/) for the next command to work.

Note:

If here string <<< does not work in your shell then you can echo and pipe as

echo "$@" | sed ...

Errata

Here e script

Solution 6 - Windows

just FYI - at least for my git version 2.26.2.windows.1 e.g. if I have a path like C:\dev\work_setup\msk, I can go directly to Git Bash and type

cd "C:\dev\work_setup\msk"

this will result in current folder being changed to /c/dev/work_setup/msk - so this type of conversion seems to be done automatically, as long as I put the Windows path inside double quotes. Unfortunately I don't have references to original documentation that would back that up.

Solution 7 - Windows

My solution works with a list of folders/files and it's done in 2 steps. Suppose you would like to replace a path from D:\example to /example for a list of file where this Windows path has been repetead.

The first step it changes the backlashes into slashes

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

Note that parent-folder could be root (/) or whatever you like and -d'\n' parameter is necessary if you have filenames or folder names with white spaces.

Second step it substitutes the D:/example into /example:

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

I wanted to share this solution since it tooks me some time to make this 2 lines but it has been really helpfull job (I'm migrating a Windows App to a Linux Server with tons of Windows paths inside').

Solution 8 - Windows

The answer of @hello_earth is misleading, due to Windows path must be double backslashed like:

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

otherwise the shell will find escape-sequences.

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionTomilov AnatoliyView Question on Stackoverflow
Solution 1 - WindowsanishsaneView Answer on Stackoverflow
Solution 2 - WindowsRody OldenhuisView Answer on Stackoverflow
Solution 3 - WindowsZYinMDView Answer on Stackoverflow
Solution 4 - WindowsPodView Answer on Stackoverflow
Solution 5 - WindowshIpPyView Answer on Stackoverflow
Solution 6 - Windowshello_earthView Answer on Stackoverflow
Solution 7 - WindowsAlessandro RView Answer on Stackoverflow
Solution 8 - Windowsuser12425014View Answer on Stackoverflow