【问题标题】:How-To get root directory of given path in bash?如何在 bash 中获取给定路径的根目录?
【发布时间】:2014-08-29 04:35:24
【问题描述】:

我的脚本:

    #!/usr/bin/env bash
    PATH=/home/user/example/foo/bar
    mkdir -p /tmp/backup$PATH

现在我想获取“$PATH”的第一个文件夹:/home/

    cd /tmp/backup
    rm -rf ./home/
    cd - > /dev/null

我怎样才能像上面的示例一样始终检测到第一个文件夹? "dirname $PATH" 只返回 "/home/user/example/foo/"。

提前致谢! :)

【问题讨论】:

    标签: bash path directory dirname


    【解决方案1】:

    如果PATH 总是有一个绝对形式,你可以做一些技巧,比如

    ROOT=${PATH#/} ROOT=/${ROOT%%/*}
    

    或者

    IFS=/ read -ra T <<< "$PATH"
    ROOT=/${T[1]}
    

    但我还应该补充一点,最好使用其他变量而不是使用PATH,因为它会改变您搜索二进制文件的目录,除非您真的打算这样做。

    您还可以选择通过readlink -freadlink -m 将路径转换为绝对形式:

    ABS=$(readlink -m "$PATH")
    

    你也可以参考我的功能getabspath

    【讨论】:

    • 对不起,我不明白这个。 o.O 但是谢谢。
    • 太糟糕了。祝你好运:)
    【解决方案2】:

    获得第一个火药:

    path=/home/user/example/foo/bar
    mkdir -p "/tmp/backup$path"
    cd /tmp/backup
    arr=( */ )
    echo "${arr[0]}"
    

    PS:切勿在脚本中使用 PATH 变量,因为它会覆盖默认 PATH,并且您的脚本将无法执行许多系统实用程序

    编辑:也许这对你有用:

    IFS=/ && set -- $path; echo "$2"
    home
    

    【讨论】:

    • 我想,用户想从中提取home
    • How can I always detect the first folder like the example above不是很清楚。我将其解释为 OP 试图从 /tmp/backup 路径获取第一个目录。
    • 我开始评论的目的是感谢您和 +1 对PATH 变量的警告。 :) 然后意识到答案可能不满足OP的要求。
    • 嗯,在那种情况下,konsolebox 可能正确地解释了它
    • 来自问题:And now I want to get first folder of "$PATH": /home/
    【解决方案3】:

    你可以试试这个 awk 命令:

     basedirectory=$(echo "$PATH" | awk -F "/" '{print $2}')
    

    此时basedirectory 将是字符串home 然后你写:

    rm -rf ./"$basedirectory"/
    

    【讨论】:

    • 这看起来不错,但它不起作用。 $basedirectory 始终为空。不过谢谢! :)
    • 很高兴您找到了解决方案。无论如何你是对的,我只是编辑了脚本。不知道为什么写{print $1},发之前我也测试了一下。现在它应该可以工作了。
    • 这也适用于沿路径获取第 n 个目录,例如basedirectory=$(echo "$PATH" | awk -F "/" '{print $3}')
    【解决方案4】:

    我找到了解决办法:

        #/usr/bin/env bash
        DIRECTORY="/home/user/example/foo/bar"
        BASE_DIRECTORY=$(echo "$DIRECTORY" | cut -d "/" -f2)
        echo "#$BASE_DIRECTORY#";
    

    这总是返回第一个目录。在此示例中,它将返回以下内容:

        #home#
    

    感谢@condorwasabi 提出的关于 awk 的想法! :)

    【讨论】:

    • 如果你的路径是相对的并且看起来像这样:dir1/in/dir2 那么你应该定位字段-f1 而不是-f2
    【解决方案5】:

    纯 bash:

    DIR="/home/user/example/foo/bar"
    [[ "$DIR" =~ ^[/][^/]+ ]] && printf "$BASH_REMATCH"
    

    易于调整正则表达式。

    【讨论】:

      【解决方案6】:

      你可以使用dirname...

      #/usr/bin/env bash
      DIRECTORY="/home/user/example/foo/bar"
      BASE_DIRECTORY=$(dirname "${DIRECTORY}")
      echo "#$BASE_DIRECTORY#";
      

      输出以下内容...

      /home/user/example/foo
      

      【讨论】:

      • 解决方案应该输出home而不是/home/user/example/foo
      【解决方案7】:

      获取VAR的第一个目录组件:

      echo ${VAR%${VAR#/*/}}
      

      所以,如果VAR="/path/to/foo",则返回/path/

      解释:

      ${VAR#X} 去掉前缀 X 并返回余数。所以如果VAR=/path/to/foo,那么/*/匹配前缀/path/,表达式返回后缀to/foo

      ${VAR%X} 去掉后缀X。通过插入${VAR#X} 的输出,它会去掉后缀并返回前缀。

      如果您可以保证您的路径格式正确,这是一种方便的方法。它不适用于某些路径,例如 //path/to/foopath/to/foo,但您可以通过进一步分解字符串来处理这种情况。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2010-12-14
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2018-05-31
        • 1970-01-01
        相关资源
        最近更新 更多