关于linux:如何在bash中获取文件的绝对目录?

How do I get the absolute directory of a file in bash?

我编写了一个bash脚本,它将输入文件作为参数并读取它。此文件包含一些指向所用其他文件的路径(相对于其位置)。

我希望脚本转到包含输入文件的文件夹,以执行进一步的命令。

那么,如何从输入文件中获取文件夹(并且只获取文件夹)?(在Linux中)


要获取完整路径,请使用:

1
readlink -f relative/path/to/file

要获取文件的目录:

1
dirname relative/path/to/file

您还可以将这两种方法结合起来:

1
dirname $(readlink -f relative/path/to/file)

如果您的系统上没有readlink -f,您可以使用这个*:

1
2
3
4
5
6
function myreadlink() {
  (
  cd"$(dirname $1)"         # or  cd"${1%/*}"
  echo"$PWD/$(basename $1)" # or  echo"$PWD/${1##*/}"
  )
}

请注意,如果只需要移动到指定为相对路径的文件的目录,则不需要知道绝对路径,相对路径是完全合法的,因此只需使用:

1
cd $(dirname relative/path/to/file)

如果您希望(在脚本运行时)返回到原始路径,请在完成后使用pushd而不是cdpopd

*虽然上面的myreadlink在这个问题的上下文中已经足够好了,但是它相对于上面建议的readlink工具有一些限制。例如,它没有正确地跟踪指向不同basename文件的链接。


看一下realpath的手册页,我用它和类似的东西:

CONTAININGDIR=$(realpath ${FILEPATH%/*})

做你想做的事。


这对文件和文件夹都有效:

1
2
3
4
5
6
7
8
9
absPath(){
    if [[ -d"$1" ]]; then
        cd"$1"
        echo"$(pwd -P)"
    else
        cd"$(dirname"$1")"
        echo"$(pwd -P)/$(basename"$1")"
    fi
}

1
2
3
$cat abs.sh
#!/bin/bash
echo"$(cd"$(dirname"$1")"; pwd -P)"

一些解释:

  • 这个脚本得到相对路径作为参数"$1"
  • 然后我们得到该路径的dirname部分(您可以将dir或file传递给这个脚本):dirname"$1"
  • 然后我们将cx1〔10〕引入这个相对方向。
  • 得到绝对路径。-P选项将避免符号链接
  • 作为最后一步,我们决定
  • 然后运行脚本:

    1
    abs.sh your_file.txt

    在Github上尝试我们的新bash库产品realpath lib,我们已经免费和无障碍地提供给社区使用。它很干净,简单,有很好的文档记录,所以很好地学习。你可以做到:

    1
    get_realpath

    此功能是库的核心:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    if [[ -f"$1" ]]
    then
        # file *must* exist
        if cd"$(echo"${1%/*}")" &>/dev/null
        then
            # file *may* not be local
            # exception is ./file.ext
            # try 'cd .; cd -;' *works!*
            local tmppwd="$PWD"
            cd - &>/dev/null
        else
            # file *must* be local
            local tmppwd="$PWD"
        fi
    else
        # file *cannot* exist
        return 1 # failure
    fi

    # reassemble realpath
    echo"$tmppwd"/"${1##*/}"
    return 0 # success

    }

    它是bash 4+,不需要任何依赖项,还提供get_dirname、get_filename、get_stemname和validate_path。


    上面的答案有问题,输入的文件有"./"如"./my file.txt"

    解决方法(很多):

    1
    2
    3
        myfile="./somefile.txt"
        FOLDER="$(dirname $(readlink -f"${ARG}"))"
        echo ${FOLDER}


    我一直在使用readlink-f在Linux上工作

    所以

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    FULL_PATH=$(readlink -f filename)
    DIR=$(dirname $FULL_PATH)

    PWD=$(pwd)

    cd $DIR

    #<do more work>

    cd $PWD