Bash script to convert windows path to linux path

2020-06-17 06:34发布

问题:

I'm new to shell scripting and trying to accomplish following, converting a windows path to a linux path and navigating to that location:

Input: cdwin "J:\abc\def" Action: cd /usr/abc/def/

So, I'm changing the following:

"J:" -> "/usr"

and

"\" -> "/"

This is my try, but it doesn't work. It just returns a blank if i echo it:

function cdwin(){
    line="/usrfem/Projects$1/" | sed 's/\\/\//g' | sed 's/J://'
    cd $line
}

回答1:

You need to catch the variable and then process it.

For example this would make it:

function cdwin(){
    echo "I receive the variable --> $1"
    line=$(sed -e 's#^J:##' -e 's#\\#/#g' <<< "$1")
    cd "$line"
}

And then you call it with

cdwin "J:\abc\def"

Explanation

The command

line=$(sed -e 's#^J:##' -e 's#\\#/#g' <<< "$1")

is equivalent to

line=$(echo $1 | sed -e 's#^J:##' -e 's#\\#/#g')

and replaces every \ with /, saving the result into the var line. Note it uses another delimiter, #, to make it more readable. It also removes the leading J:.



回答2:

sed allows alternative delimiters so better to not to use /.

Try this sed command:

sed -e 's~\\~/~g' -e 's~J:~/usr~' <<< "$line"


回答3:

You don't even need to use sed (although there's nothing wrong with using sed). This works for me using bash string substitution:

function cdwin() {
  line=${1/J://usr}
  line=${line//\\//}
  cd "$line"
}

cdwin 'J:\abc\def'

Substitution works as follows (simplification):

${var/find/replace} 

and double slash means replace all:

${var//findall/replace}

In argument 1, replace the first instance of J: with /usr:

${1/J://usr}

In variable line replace all (//) backslashes (escaped, \\) with (/) forwardslash (/):

${line//\\//}

echo the output of any of those to see how they work



回答4:

My code is inspired by the top post but modified to work with any drive on windows 10 while running on native ubuntu (aka WSL).

You can comment out the debugging lines if you just want the function.

You can comment out the cd line if you just want output path

function cdwin() {
    # Converts Windows paths to WSL/Ubuntu paths, prefixing /mnt/driveletter and preserving case of the rest of the arguments,
    # replacing backslashed with forwardslashes
    # example: 
    # Input -> "J:\Share"
    # Output -> "/mnt/j/Share"
    echo "Input --> $1" #for debugging
    line=$(sed -e 's#^\(.\):#/mnt/\L\1#' -e 's#\\#/#g' <<< "$1")
    #Group the first character at the beginning of the string. e.g. "J:\Share", select "J" by using () but match only if it has colon as the second character
    #replace J: with /mnt/j
    #\L = lowercase , \1 = first group (of single letter)
    # 2nd part of expression
    #replaces every \ with /, saving the result into the var line. 
    #Note it uses another delimiter, #, to make it more readable.
    echo "Output --> $line" #for debugging
    cd "$line" #change to that directory
}