我编写了一个 bash 脚本,它将输入文件作为参数并读取它。
该文件包含一些路径(相对于其位置)到所使用的其他文件。
我希望脚本转到包含输入文件的文件夹,以执行进一步的命令。
那么,如何从输入文件中获取文件夹(并且只是文件夹)?(在 Linux 中。)
要获得完整路径,请使用:
readlink -f relative/path/to/file
要获取文件的目录:
dirname relative/path/to/file
您也可以将两者结合起来:
dirname $(readlink -f relative/path/to/file)
如果readlink -f
在您的系统上不可用,您可以使用此*:
function myreadlink() {
(
cd "$(dirname $1)" # or cd "${1%/*}"
echo "$PWD/$(basename $1)" # or echo "$PWD/${1##*/}"
)
}
请注意,如果您只需要移动到指定为相对路径的文件的目录,则不需要知道绝对路径,相对路径是完全合法的,因此只需使用:
cd $(dirname relative/path/to/file)
如果您希望(在脚本运行时)返回到原始路径,请使用pushd
代替cd
,并popd
在完成后使用。
*虽然myreadlink
以上在这个问题的背景下已经足够好,但相对于readlink
上面建议的工具,它有一些限制。例如,它没有正确地跟随指向具有不同basename
.
这将适用于文件和文件夹:
absPath(){
if [[ -d "$1" ]]; then
cd "$1"
echo "$(pwd -P)"
else
cd "$(dirname "$1")"
echo "$(pwd -P)/$(basename "$1")"
fi
}
$cat abs.sh
#!/bin/bash
echo "$(cd "$(dirname "$1")"; pwd -P)"
一些解释:
"$1"
dirname "$1"
cd "$(dirname "$1");
进入这个相对目录pwd -P
并获得绝对路径。该-P
选项将避免符号链接echo
我们然后运行你的脚本:
abs.sh your_file.txt
在 GitHub 上试用我们新的 Bash 库产品realpath-lib,我们已将其提供给社区,供免费且不受阻碍地使用。它干净、简单且有据可查,因此非常值得学习。你可以做:
get_realpath <absolute|relative|symlink|local file path>
这个函数是库的核心:
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”
解决方法(许多):
myfile="./somefile.txt"
FOLDER="$(dirname $(readlink -f "${ARG}"))"
echo ${FOLDER}
我一直在使用 readlink -f 在 linux 上工作
所以
FULL_PATH=$(readlink -f filename)
DIR=$(dirname $FULL_PATH)
PWD=$(pwd)
cd $DIR
#<do more work>
cd $PWD