daily pastebin goal
51%
SHARE
TWEET

WSL <--> Windows Path Conversion and `cd`

jkool702 Sep 14th, 2018 189 in 300 days
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1.  
  2. mycd() {
  3. # 'cd' to either unix-style or windows-style paths. The code automatically converts windows--style paths to unix-sytle paths.
  4. # If: a) target destination begins with '__:\' (where __ is a 1-2 letter drive name) OR
  5. #     b) the target destination contains 0 '/' characters and 1+ '\' characters,
  6. # THEN the windows-->unix conversion will be performed
  7.  
  8.         local cdTarget=""
  9.         local cdFlags=""
  10.         local cdFlagCur="init"
  11.         local noLiteralFlag=0
  12.  
  13.         # get literal input to 'mycd' unless 1st input is '--no-literal' flag
  14.         if ! [[ -z "${*}" ]] && [[ ${1,,} =~ ^-+no-?lit(eral)?$ ]]; then
  15.                 shift 1
  16.                 cdTarget="${*}"
  17.                 noLiteralFlag=1
  18.         else
  19.                 cdTarget="$(getLiteralInput)"
  20.         fi
  21.  
  22.         # remove any flags intended for use with cd
  23.         while [[ "$cdTarget" != "$(echo "$cdTarget" | sed -E s/'^.*-[LPe\@] +.*$'//)" ]] && ! [[ -z "${cdFlagCur}" ]]
  24.         do
  25.                 cdFlagCur="$(echo "${cdTarget}" | sed -E s/'[^| ](-[LPe\@]) '/'\1'/ | sed -E s/'^'"${cdTarget}"'$'//)"
  26.                 cdTarget="$(echo "${cdTarget}" | sed -E s/'^(.*[^ ] )? *-[LPe\@] +([^ ].*)$'/'\1\2'/)"
  27.  
  28.                 if ! [[ -z "${cdFlagsCur}" ]]; then
  29.                         cdFlags="${cdFlags} ${cdFlagCur}"
  30.                 fi
  31.         done
  32.  
  33.         # if the file path matches a windows-style path, run conversion function and then call 'cd'  ;  otherwise directly call 'cd'
  34.         if [[ -z "$(echo "$cdTarget" | sed -E s/'^([a-zA-Z]{1,2}:)?\\.*$'//)" ]] || ( [[ "${cdTarget}" == "${cdTarget//\//}" ]] && [[ "${cdTarget}" != "${cdTarget/\\/}" ]] ); then
  35.                 # input is windows-style path
  36.                 if [[ -z "${cdFlags}" ]]; then
  37.                         eval "\cd $(convertPath --no-literal -w2l "${cdTarget}")"
  38.                 else
  39.                         cdTarget="$(convertPath --no-literal --no-quote -w2l "${cdTarget}")"
  40.  
  41.                         #cdTarget="'${cdFlags//\'/\'\"\'\"\'} ${cdTarget//\'/\'\"\'\"\'}'"
  42.                         cdTarget="$(echo "'$(echo "${cdFlags//\'/\'\"\'\"\'}" | sed -E s/'^ *([^( *$)]*) *$'/'\1'/) $(echo "${cdTarget//\'/\'\"\'\"\'}" | sed -E s/'^ *([^( *$)]*) *$'/'\1'/)'"  | sed -E s/'^ *'"'"' *([^( *$)]*) *'"'"' *$'/''"'"'\1'"'"''/)"
  43.  
  44.                        eval "\cd ${cdTarget}"
  45.                fi
  46.        else
  47.                # input is unix-style path
  48.                if (( $noLiteralFlag == 1 )); then
  49.                        cdTarget="$(echo "'$(echo "${cdFlags//\'/\'\"\'\"\'}" | sed -E s/'^ *([^( *$)]*) *$'/'\1'/) $(echo "${cdTarget//\'/\'\"\'\"\'}" | sed -E s/'^ *([^( *$)]*) *$'/'\1'/)'"  | sed -E s/'^ *'"'"' *([^( *$)]*) *'"'"' *$'/''"'"'\1'"'"''/)"
  50.  
  51.                        eval "\cd ${cdTarget}"
  52.                else
  53.                        eval "\cd $(getLiteralInput)"
  54.                fi
  55.        fi
  56.     }
  57.    
  58.    
  59. convertPath() {
  60. # Converts path from Windows style to Linux style
  61. # Use '-linux2win' or '-wsl2win' or '-l2w' flag to force Linux to Windows conversion
  62. # Use '-win2linux' or '-win2wsl' or '-w2l' flag to force Windows to Linux conversion
  63. # By default, 'getLiteralInput' is used to get the input.
  64. #    To use the "standard" command line input, use the '--no-literal' or '-nl' flag.
  65. #    Note: this flag is required if this function is called by any startup scripts (e.g., ~/.bashrc).
  66. # By default, the output will be single quoted.
  67. #    To force escaping of shell characters instead, use the '--shell-escape' or '-se' flag.
  68. #    To force the output to be unquoted and unescaped, use the '--no-quote' or '-nq' flag.
  69.  
  70.        local opType=""
  71.        local shellEscapeFlag=0
  72.        local noQuoteFlag=0
  73.        local inputLiteral=""
  74.        local inputCur=""
  75.        local fnCur=""
  76.        local fnNew=""
  77.  
  78.        if [[ ${*} =~ ^.*-+[Nn][Oo]?-?[Ll]([Ii][Tt]([Ee][Rr][Aa][Ll])?)?.*$ ]]; then
  79.                inputLiteral="$(echo "${*}" | sed -E s/'^(.*[^-])? ?-+[Nn][Oo]-?[Ll]([Ii][Tt]([Ee][Rr][Aa][Ll])?)? ?(.*)$'/'\1 \4'/)"
  80.        else
  81.                inputLiteral="$(getLiteralInput)"
  82.        fi
  83.  
  84.        if [[ ${inputLiteral} =~ ^.*-+[Ss]([Hh][Ee][Ll][Ll])?-?[Ee]([Ss][Cc][Aa][Pp][Ee])?.*$ ]]; then
  85.                inputLiteral="$(echo "${inputLiteral}" | sed -E s/'^(.*[^-])? ?-+[Ss]([Hh][Ee][Ll][Ll])?-?[Ee]([Ss][Cc][Aa][Pp][Ee])? ?(.*)$'/'\1 \4'/)"
  86.                shellEscapeFlag=1
  87.        fi
  88.  
  89.        if [[ ${inputLiteral} =~ ^.*-+[Nn][Oo]?-?[Qq]([Uu][Oo][Tt][Ee])?.*$ ]]; then
  90.                inputLiteral="$(echo "${inputLiteral}" | sed -E s/'^(.*[^-])? ?-+[Nn][Oo]?-?[Qq]([Uu][Oo][Tt][Ee])? ?(.*)$'/'\1 \3'/)"
  91.                noQuoteFlag=1
  92.        fi
  93.  
  94.        if ! [[ ${inputLiteral} =~ ^.*-+(([Ll]|[Ll][Ii][Nn][Uu][Xx]|[Ww][Ss][Ll])2([Ww]|[Ww][Ii][Nn]|[Ww][Ii][Nn][Dd][Oo][Ww][Ss])|([Ww]|[Ww][Ii][Nn]|[Ww][Ii][Nn][Dd][Oo][Ww][Ss])2([Ll]|[Ll][Ii][Nn][Uu][Xx]|[Ww][Ss][Ll])).*$ ]]; then
  95.  
  96.                # Determine conversion type automatically
  97.  
  98.                if [[ -z "$(echo "${inputLiteral}" | sed -E s/'^ ?[a-zA-Z]{1,2}:\\.*'//)" ]]; then
  99.                        opType="w2l"
  100.                elif [[ -z "$(echo "${inputLiteral}" | sed -E s/'^ ?\/.*'//)" ]]; then
  101.                        opType="l2w"
  102.                else
  103.                        # count the nnumber of '\' vs '/' characters in the input
  104.                        local nw=0
  105.                        local nl=0
  106.                        local inTempW=""
  107.                        local inTempL=""
  108.  
  109.                        inTempW="${inputLiteral}"
  110.                        inTempL="${inputLiteral}"
  111.  
  112.                        while ! [[ "${inTempW}" == "$(echo "${inTempW}" | sed -E s/'\\([^ \(\)\[\]\{\}\"\'"'"'\$\&\!\@\^\*])'/'\1'/)" ]]
  113.                        do
  114.                                inTempW="$(echo "${inTempW}" | sed -E s/'\\([^ \(\)\[\]\{\}\"\'"'"'\$\&\!\@\^\*])'/'\1'/)"
  115.                                nw=$((( $nw + 1 )))
  116.                        done
  117.  
  118.                        while ! [[ "${inTempL}" == "$(echo "${inTempL}" | sed -E s/'\/'/''/)" ]]
  119.                        do
  120.                                inTempL="$(echo "${inTempL}" | sed -E s/'\/'/''/)"
  121.                                nl=$((( $nl + 1 )))
  122.                        done
  123.  
  124.                        if (( $nl > $nw )); then
  125.                                opType="l2w"
  126.                        else
  127.                                opType="w2l"
  128.                        fi
  129.  
  130.                fi
  131.  
  132.        else
  133.  
  134.                if [[ ${inputLiteral} =~ ^.*-+([Ll]|[Ll][Ii][Nn][Uu][Xx]|[Ww][Ss][Ll])2([Ww]|[Ww][Ii][Nn]|[Ww][Ii][Nn][Dd][Oo][Ww][Ss]).*$ ]]; then
  135.                        opType="l2w"
  136.                        inputLiteral="$(echo "${inputLiteral}" | sed -E s/'^(.*[^-])? ?-+([Ll]|[Ll][Ii][Nn][Uu][Xx]|[Ww][Ss][Ll])2([Ww]|[Ww][Ii][Nn]|[Ww][Ii][Nn][Dd][Oo][Ww][Ss]) ?(.*)$'/'\1 \4'/)"
  137.                elif [[ ${inputLiteral} =~ ^.*-+([Ww]|[Ww][Ii][Nn]|[Ww][Ii][Nn][Dd][Oo][Ww][Ss])2([Ll]|[Ll][Ii][Nn][Uu][Xx]|[Ww][Ss][Ll]).*$ ]]; then
  138.                        opType="w2l"
  139.                        inputLiteral="$(echo "${inputLiteral}" | sed -E s/'^(.*[^-])? ?-+([Ww]|[Ww][Ii][Nn]|[Ww][Ii][Nn][Dd][Oo][Ww][Ss])2([Ll]|[Ll][Ii][Nn][Uu][Xx]|[Ww][Ss][Ll]) ?(.*)$'/'\1 \4'/)"
  140.                fi
  141.  
  142.        fi
  143.  
  144.        if [[ -z "$opType" ]]; then
  145.                opType="w2l"
  146.        fi
  147.  
  148.        # expand any part af the input that is a variable name (i.e., '$____')
  149.        while [[ $inputLiteral =~ ^.*\$\(.*\).*$ ]]
  150.        do
  151.                inputLiteral="$(eval "echo \"${inputLiteral}\"" | sed -E s/'^(eval )?(.*)$'/'\2'/)"
  152.        done
  153.  
  154.        # remove spaces from start and end of the path
  155.        inputLiteral="$(echo "${inputLiteral}" | sed -E s/' *([^ ].*[^( *$)]) *$'/'\1'/)"
  156.  
  157.        if [[ "$opType" == "l2w" ]]; then
  158.  
  159.                if ! [[ -z "$(echo "${inputLiteral}" | sed -E s/'^'"'"'.*'"'"'$'//)" ]]; then
  160.                        # unescape commonly espaced shell characters
  161.                        inputLiteral="${inputLiteral//\\\(//\(}"
  162.                        inputLiteral="${inputLiteral//\\\)//\)}"
  163.                        inputLiteral="${inputLiteral//\\\}//\}}"
  164.                        inputLiteral="${inputLiteral//\\\{//\{}"
  165.                        inputLiteral="${inputLiteral//\\\&//\&}"
  166.                        inputLiteral="${inputLiteral//\\\\//\\}"
  167.                        inputLiteral="${inputLiteral//\\ // }"
  168.                else
  169.                        # remove single quotes
  170.                        inputLiteral="$(echo "${inputLiteral}" | sed -E s/'^'"'"'(.*)'"'"'$'/'\1'/)"
  171.                fi
  172.  
  173.                # fix strange error with '/_', where _ is a lower-case character
  174.                while [[ "${inputLiteral}" != "$(echo "${inputLiteral}" | sed -E s/'^.*\/.*$'//)" ]]
  175.                do
  176.                        inputLiteral="$(echo "${inputLiteral}" | sed -E s/'\/(.)'/'\\\1'/)"
  177.                done
  178.  
  179.                # remove the '.' from hidden files
  180.                inputLiteral="${inputLiteral//\\\./\\}"
  181.  
  182.                # extract 1st space-seperated word
  183.                inputCur="$(echo "${inputLiteral}" | sed -E s/'^ *([^ ]* *).*$'/'\1'/ | sed -E s/'^(.*) $'/'\1'/)"
  184.                inputLiteral="$(echo "${inputLiteral}" | sed -E s/'^ *[^ ]* ?(.*)$'/'\1'/)"
  185.  
  186.                # convert word
  187.                #fnCur="$(echo "${inputCur//\//\\}" | sed -E s/'^\.\\(.*)$'/'\1'/ | sed -E s/'^\\mnt\\([a-zA-Z]+)\\?'/'\U\1:\\'/ | sed -E s/'^([a-zA-Z]+:\\)(.*[^(\\? +)])?( +|\\ +)$'/'\1\2'/)"
  188.                fnCur="$(echo "${inputCur//\//\\}" | sed -E s/'^\.\\(.*)$'/'\1'/ | sed -E s/'^\\mnt\\([a-zA-Z]+)\\?'/'\U\1:\\'/ | sed -E s/'^([a-zA-Z]+:\\)(.*[^(\\ | )])?( +|\\ +)$'/'\1\2'/)"
  189.  
  190.                while ! [[ -z "$(echo "${inputLiteral}" | sed -E s/'^ *$'//)" ]]; do
  191.  
  192.                        # extract next space-seperated word
  193.                        inputCur="$(echo "${inputLiteral}" | sed -E s/'^ *([^ ]* *).*$'/'\1'/ | sed -E s/'^(.*) $'/'\1'/)"
  194.                        inputLiteral="$(echo "${inputLiteral}" | sed -E s/'^ *[^ ]* *(.*)$'/'\1'/)"
  195.  
  196.                        # convert word
  197.                        fnNew="$(echo "${inputCur//\//\\}" | sed -E s/'^\.\\(.*)$'/'\1'/ | sed -E s/'^\\mnt\\([a-zA-Z]+)\\?'/'\U\1:\\'/ | sed -E s/'^([a-zA-Z]+:\\)(.*[^(\\ | )])?( +|\\ +)$'/'\1\2'/)"
  198.                        #fnNew="$(echo "${inputCur//\//\\}" | sed -E s/'^\.\\(.*)$'/'\1'/ | sed -E s/'^\\mnt\\([a-zA-Z]+)\\?'/'\U\1:\\'/ | sed -E s/'^(([a-zA-Z]+:\\)?[^(\\? +$)]*)( +|\\ +)$'/'\1'/)"
  199.  
  200.                        # remove '.' characters from the start of the new word unless it is the file extension
  201.                #       if ! [[ -z "$(echo "${inputLiteral}" | sed -E s/'^(\/mnt|\.\/).*$'// | sed -E s/'^ *$'//)" ]]; then
  202.                #               fnNew="$(echo ${fnNew} | sed -E s/'^\.(.*)$'/'\1'/)"
  203.                #       elif ! [[ -z "${inputLiteral}" ]]; then
  204.                #               inputLiteral="$(echo ${inputLiteral} | sed -E s/'^\.(.*)$'/'\1'/)"
  205.                #       fi
  206.  
  207.                        # combine new word with previous words. Add ';' in between if the new word is the start of a new path
  208.                        if [[ -z "${fnNew}" ]]; then
  209.                                inputLiteral=""
  210.                        elif [[ -z "$(echo "${fnNew}" | sed -E s/'^[a-zA-Z]+:\\.*$'//)" ]]; then
  211.                                fnCur="${fnCur} ; ${fnNew}"
  212.                        else
  213.                                fnCur="${fnCur} $(echo "${fnNew}" | sed -E s/'^ *([^ ].*)$'/'\1'/)"
  214.                        fi
  215.                done
  216.  
  217.        elif [[ "$opType" == "w2l" ]]; then
  218.  
  219.                if ! [[ -z "$(echo "${inputLiteral}" | sed -E s/'^'"'"'.*'"'"'$'//)" ]]; then
  220.                        inputLiteral="${inputLiteral//\\ / }"
  221.                fi
  222.  
  223.                # extract first space-seperated word
  224.                inputCur="$(echo "${inputLiteral}" | sed -E s/'^ *([^ ]* *).*$'/'\1'/ | sed -E s/'^(.*) $'/'\1'/)"
  225.                inputLiteral="$(echo "${inputLiteral}" | sed -E s/'^ *[^ ]* *(.*)$'/'\1'/)"
  226.  
  227.                # convert word
  228.                fnCur="$(echo "${inputCur//\\/\/}" | sed -E s/'^ *([a-zA-Z]*):\/?'/'\/mnt\/\L\1\/'/ | sed -E s/'^\/mnt\/\/+(.*)$'/':\/\1'/)"
  229.                fnCur="${fnCur//\\ / }"
  230.  
  231.                while ! [[ -z "$(echo "${inputLiteral}" | sed -E s/'^ *$'//)" ]]; do
  232.  
  233.                        # extract next space-seperated word
  234.                        inputCur="$(echo "${inputLiteral}" | sed -E s/'^ *([^ ]* *).*$'/'\1'/ | sed -E s/'^(.*) $'/'\1'/)"
  235.                        inputLiteral="$(echo "${inputLiteral}" | sed -E s/'^ *[^ ]* *(.*)$'/'\1'/)"
  236.  
  237.                        # convert word
  238.                        fnNew="$(echo "${inputCur//\\/\/}" | sed -E s/'^ *([a-zA-Z]*):\/?'/'\/mnt\/\L\1\/'/ | sed -E s/'^\/mnt\/\/+(.*)$'/':\/\1'/)"
  239.                        fnNew="${fnNew//\\ / }"
  240.  
  241.                        # combine new word with previous words. Add ';' in between if the new word is the start of a new path
  242.                        if [[ -z "${fnNew}" ]]; then
  243.                                inputLiteral=""
  244.                        elif [[ -z "$(echo "${fnNew}" | sed -E s/'^(\/mnt\/|:\/).*$'//)" ]]; then
  245.                                fnCur="${fnCur} ; ${fnNew}"
  246.                        else
  247.                                fnCur="${fnCur} $(echo "${fnNew}" | sed -E s/'^ *(.*)$'/'\1'/)"
  248.                        fi
  249.                done
  250.  
  251.        fi
  252.  
  253.        if [[ "${fnCur//" ; "/}" != "${fnCur}" ]]; then
  254.                # outputting multiple converted paths. Add a ';' to the end of the last one to maintain consistency.
  255.                fnCur="${fnCur} ;"
  256.        fi
  257.  
  258.        if [[ "$opType" == "l2w" ]]; then
  259.                # unescape spaces for output to windows
  260.                fnCur=${fnCur//"\ "/ }
  261.        fi
  262.  
  263.        # echo output
  264.        if (( $shellEscapeFlag == 1 )); then
  265.                echo "$(escapeShellChars "${fnCur}")"
  266.        else
  267.                if (( $noQuoteFlag == 0 )); then
  268.                        fnCur="'${fnCur//\'/\'\"\'\"\'}'"
  269.                fi
  270.                echo -e "${fnCur//" ; "/ ; \\n}"
  271.        fi
  272.     }
  273.    
  274. getLiteralInput() {
  275. # Use the "history" function to get the literal input to a function, even if that input was not quoted
  276. # One set of single quotes surrounding the entire input will be removed, if they exist
  277. #
  278. # NOTE: this will give the last input entered into the terminal by a human. Any inputs into this function are ignored.
  279. #    It will NOT give inputs to sub-functions and should NOT be relied upon by auto-run functions (e.g., functions called by ~/.bashrc).
  280. #
  281. # NOTE: This CAN work with 'forbidden' characters (like '(' and ')' and '&') WITHOUT escaping or single quoting them.
  282. #    To enable this functionality, use 'foo # argIn1 argIn2 ... argInN'. The inputs never are evaluated but are still recorded in the history.
  283. #    To always anable this functionality for a function that uses getLiteralInput' to get its inputs, alias the function to: alias foo='\foo #'
  284. #    The '#' will be automatically removed as long as it is immediately after the function call and before any inputs.
  285.  
  286.         local literalIn=""
  287.  
  288.         literalIn="$(echo "$(history 1)" | sed -E s/"^ *[0-9]+ +[^ ]+ +(.*)$"/'\1'/ | sed -E s/"^ *('? *.*[^(?: *'? *$)].* *'?) *$"/'\1'/ | sed -E s/"^'([^'$]*)'$"/'\1'/ | sed -E s/'^ *\# *(.*)$'/'\1'/)"
  289.  
  290.        if ! [[ -z "$1" ]] && [[ $1 =~ ^-+([Aa][Dd][Dd])?-?[Qq]([Uu][Oo][Tt][Ee][Ss]?)?$ ]]; then
  291.                literalIn="${literalIn//\'/\\\'}"
  292.                literalIn="'${literalIn//\\\\\'/\\\'}'"
  293.  
  294.                if [[ "$(history 1)" != "$(echo "$(history 1)" | sed -E s/'^.*[Gg]et[Ll]iteral[Ii]nput.*$'/''/)" ]]; then
  295.                        literalIn="$(echo "${literalIn}" | sed -E s/'^ *[Gg]et[Ll]iteral[Ii]nput *(.*)$'/'\1'/)"
  296.                fi
  297.        fi
  298.  
  299.        echo ${literalIn}
  300.     }
RAW Paste Data
We use cookies for various purposes including analytics. By continuing to use Pastebin, you agree to our use of cookies as described in the Cookies Policy. OK, I Understand
 
Top