我编写了一个bash脚本,该脚本将输入文件作为参数并读取它。
该文件包含一些路径(相对于其位置),指向所使用的其他文件。
我希望脚本转到包含输入文件的文件夹,以执行更多命令。
那么,如何从输入文件中获取文件夹(以及仅文件夹)?(在Linux中。)
Answers:
要获取完整路径,请使用:
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
。
readlink -f
,不幸的这在OS X上不起作用。
brew install coreutils
得到它。 stackoverflow.com/a/4031502/1022967。
${1%/*}
或${1##*/}
替代dirname
和basename
。如果给它一个简单的文件名dirname foo.bar
,则第一个会中断(正确地是.
),第二个会中断以斜杠结尾的目录(basename /foo/bar/
会正确地是bar
)。
basename
/dirname
不是内置的),有些人可能会倾向于使用它,他们会首先看到它起作用,但是在将来某个时候突然中断,看起来似乎没有任何好处。原因。我会避免建议它作为一种选择,或者会否认它并不是真正的防弹手段。
看一下的手册页realpath
,我用它和类似的东西:
CONTAININGDIR = $(真实路径$ {FILEPATH%/ *})
做听起来像是您要尝试做的事情。
$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。
我一直在使用readlink -f在Linux上工作
所以
FULL_PATH=$(readlink -f filename)
DIR=$(dirname $FULL_PATH)
PWD=$(pwd)
cd $DIR
#<do more work>
cd $PWD
PWD
Bash中已经存在该变量,并且其值实际上是当前目录?并使用更多的报价。