Linux 如何在bash中获取文件的绝对目录?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/17577093/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-07 00:12:50  来源:igfitidea点击:

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

linuxbashshell

提问by BobMcGee

I have written a bash script that takes an input file as an argument and reads it.
This file contains some paths (relative to its location) to additional files used.

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

I would like the script to go to the folder containing the input file, to execute further commands.

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

So, how do I get the folder (and just the folder) from an input file?(In linux.)

那么,如何从输入文件中获取文件夹(以及文件夹)?(在Linux中。)

采纳答案by Chen Levy

To get the full path use:

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

readlink -f relative/path/to/file

To get the directory of a file:

要获取文件的目录:

dirname relative/path/to/file

You can also combine the two:

您还可以将两者结合起来:

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

If readlink -fis not available on your system you can use this*:

如果readlink -f在您的系统上不可用,您可以使用此*

function myreadlink() {
  (
  cd "$(dirname )"         # or  cd "${1%/*}"
  echo "$PWD/$(basename )" # or  echo "$PWD/${1##*/}"
  )
}

Note that if you only need to move to a directory of a file specified as a relative path, you don't need to know the absolute path, a relative path is perfectly legal, so just use:

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

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

if you wish to go back (while the script is running) to the original path, use pushdinstead of cd, and popdwhen you are done.

如果您希望返回(在脚本运行时)原始路径,请使用pushd代替cd,并popd在完成后使用。



*While myreadlinkabove is good enough in the context of this question, it has some limitation relative to the readlinktool suggested above. For example it doesn't correctly follow a link to a file with different basename.

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

回答by Mehul Rathod

I have been using readlink -f works on linux

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

so

所以

FULL_PATH=$(readlink -f filename)
DIR=$(dirname $FULL_PATH)

PWD=$(pwd)

cd $DIR

#<do more work>

cd $PWD

回答by Richard Sitze

Take a look at the man page for realpath, I use that and something like:

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

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

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

to do what it sounds like you're trying to do.

做你想做的事情。

回答by AsymLabs

Try our new Bash library product realpath-libover at GitHub that we have given to the community for free and unencumbered use. It's clean, simple and well documented so it's great to learn from. You can do:

在 GitHub 上试用我们新的 Bash 库产品realpath-lib,我们已将其提供给社区,可免费且不受阻碍地使用。它干净、简单且有据可查,因此非常值得学习。你可以做:

get_realpath <absolute|relative|symlink|local file path>

This function is the core of the library:

这个函数是库的核心:

if [[ -f "" ]]
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

}

It's Bash 4+, does not require any dependencies and also provides get_dirname, get_filename, get_stemname and validate_path.

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

回答by Mike Q

Problem with the above answer comes with files input with "./" like "./my-file.txt"

上面答案的问题是输入带有“./”的文件,比如“./my-file.txt”

Workaround (of many):

解决方法(许多):

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

回答by Jahid

This will work for both file and folder:

这将适用于文件和文件夹:

absPath(){
    if [[ -d "" ]]; then
        cd ""
        echo "$(pwd -P)"
    else 
        cd "$(dirname "")"
        echo "$(pwd -P)/$(basename "")"
    fi
}

回答by Eugen Konkov

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

Some explanations:

一些解释:

  1. This script get relative path as argument "$1"
  2. Then we get dirnamepart of that path (you can pass either dir or file to this script): dirname "$1"
  3. Then we cd "$(dirname "$1");into this relative dir
  4. pwd -Pand get absolute path. The -Poption will avoid symlinks
  5. As final step we echoit
  1. 此脚本获取相对路径作为参数 "$1"
  2. 然后我们获得该路径的dirname部分(您可以将 dir 或 file 传递给该脚本):dirname "$1"
  3. 然后我们cd "$(dirname "$1");进入这个相对目录
  4. pwd -P并获得绝对路径。该-P选项将避免符号链接
  5. 作为最后一步,我们echo

Then run your script:

然后运行你的脚本:

abs.sh your_file.txt