【问题标题】:Bash script to convert windows path to linux path将 windows 路径转换为 ​​linux 路径的 Bash 脚本
【发布时间】:2013-11-28 18:09:34
【问题描述】:

我是 shell 脚本的新手,并尝试完成以下操作,将 windows 路径转换为 ​​linux 路径并导航到该位置:

输入:cdwin "J:\abc\def" 行动:cd /usr/abc/def/

所以,我正在更改以下内容:

"J:" -> "/usr"

"\" -> "/"

这是我的尝试,但它不起作用。如果我回显它,它只会返回一个空白:

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

【问题讨论】:

  • 通过管道连续 2 次 sed 分离通常可以在 1 次 sed 中用“;”分隔例如:回声“/usrfem/Projects$1/”| sed 's|\\|/|g;s/J://' 在你的情况下

标签: linux windows bash sed path


【解决方案1】:

你需要捕获变量然后处理它。

例如这样可以:

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

然后你调用它

cdwin "J:\abc\def"

说明

命令

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

等价于

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

并用/ 替换每个\,将结果保存到变量line 中。请注意,它使用另一个分隔符#,使其更具可读性。它还会删除前导 J:

【讨论】:

  • 将替换更改为此 line=$(sed -e 's#^\(.\):#/mnt/\L\1#' -e 's#\\#/#g' &lt;&lt;&lt; "$1") 以使其适用于 Windows 10 上的 WSL/Ubuntu 的任何驱动器和路径
  • 当我运行此代码时,我收到错误-bash: cd: ~/work/projects: No such file or directory,但如果我从命令行手动运行cd ~/work/projects,它就可以工作。知道我做错了什么吗?
  • 如何使用 cdwin() ?我把它放在 .profile 吗?还是我需要创建一个同名的文件并执行 chmod +x 并将文件放在我的 PATH 中?
【解决方案2】:

sed 允许替代分隔符,因此最好不要使用/

试试这个 sed 命令:

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

【讨论】:

    【解决方案3】:

    您甚至不需要使用 sed(尽管使用 sed 并没有什么问题)。 这适用于我使用 bash 字符串替换:

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

    cdwin 'J:\abc\def'

    替换工作如下(简化):

    ${var/find/replace} 
    

    双斜线表示全部替换:

    ${var//findall/replace}
    

    在参数1 中,将J: 的第一个实例替换为/usr

    ${1/J://usr}
    

    在变量 line 中,将所有 (//) 反斜杠(转义,\\)替换为(/)正斜杠(/):

    ${line//\\//}
    

    回显其中任何一个的输出以查看它们是如何工作的

    【讨论】:

      【解决方案4】:

      我的代码受到顶帖的启发,但经过修改后可以在 Windows 10 上的任何驱动器上运行,同时在本机 ubuntu(又名 WSL)上运行。

      如果你只想要函数,你可以注释掉调试行。

      如果你只想要输出路径,你可以注释掉cd这一行

      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
      }
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2018-02-25
        • 1970-01-01
        • 1970-01-01
        • 2019-01-08
        • 2017-03-20
        • 1970-01-01
        相关资源
        最近更新 更多