Perl 将相对路径转换为绝对路径?
我不确定这些路径是否重复。给定相对路径,如何使用shell脚本确定绝对路径 例如:Perl 将相对路径转换为绝对路径?,perl,unix,shell,path,absolute-path,bash,Perl,Unix,Shell,Path,Absolute Path,Bash,我不确定这些路径是否重复。给定相对路径,如何使用shell脚本确定绝对路径 例如: relative path: /x/y/../../a/b/z/../c/d absolute path: /a/b/c/d 来自: 您还可以使用Perl one liner,例如,使用我在unix中遇到的最可靠的方法是readlink-f: $ readlink -f /x/y/../../a/b/z/../c/d /a/b/c/d 有几点需要注意: 这还具有解析所有符号链接的副作用。这可能是可取的,也可
relative path: /x/y/../../a/b/z/../c/d
absolute path: /a/b/c/d
来自:
您还可以使用Perl one liner,例如,使用我在unix中遇到的最可靠的方法是
readlink-f
:
$ readlink -f /x/y/../../a/b/z/../c/d
/a/b/c/d
有几点需要注意:
readlink
将给出一个空白结果。如果要支持不存在的路径,请改用readlink-m
。不幸的是,2005年之前发布的readlink版本上不存在此选项看看“realpath”
$ realpath
usage: realpath [-q] path [...]
$ realpath ../../../../../
/data/home
这可能有帮助:
$path = "~user/dir/../file"
$resolvedPath = glob($path); # (To resolve paths with '~')
# Since glob does not resolve relative path, we use abs_path
$absPath = abs_path($path);
使用
#目录
相对_dir=“文件夹/子文件夹/”
绝对方向=“$(cd“$相对方向”&&pwd)”
#文件
相对文件=“文件夹/子文件夹/文件”
绝对文件=“$(cd“${relative_file%/*}”和&pwd)”/“${relative_file%/}”
的结果与${relative_file%/*}
dirname“$relative_file”
的结果与${relative_file###*/}
basename“$relative_file”
使用
realpath
命令完成任务。另一种方法是使用readlink-e
(或readlink-f
)。但是默认情况下,realpath
并不经常安装。如果不能确定是否存在realpath
或readlink
,可以使用perl替换它(见下文)
使用 如果
realpath
在您的系统中不可用,则建议使用shell别名:
$ alias realpath="perl -MCwd -e 'print Cwd::realpath(\$ARGV[0]),qq<\n>'"
$ realpath path/folder/file
/home/user/absolute/path/folder/file
realpath()
是abs\u path()
fast\u abs\u path()
是abs\u path()
Cwd
以避免所指出的“未定义子例程”错误。如果要导入所有这三个函数,可以使用单个use Cwd
行:
use Cwd qw(abs_path realpath fast_abs_path);
由于多年来我多次遇到这种情况,这一次我需要一个可以在OSX和linux上使用的纯bash便携版本,所以我继续写了一个: 活生生的版本生活在这里: 但为了方便起见,这里是当前的版本(我觉得它经过了很好的测试……但我愿意接受反馈!) 要让它在纯bourne shell(sh)上运行可能并不困难,但我没有尝试……我太喜欢$FUNCNAME.:) 使用此函数,它将返回-real-path:
%% cat test.sh
#!/bin/bash
. resolve_path.inc
echo
echo "relative symlinked path:"
which mvn
echo
echo "and the real path:"
resolve_path `which mvn`
%% test.sh
relative symlinked path:
/usr/local/bin/mvn
and the real path:
/usr/local/Cellar/maven/3.2.3/libexec/bin/mvn
我想使用
realpath
,但它在我的系统(macOS)上不可用,因此我提出了以下脚本:
#/垃圾箱/垃圾箱
#名字
#absolute_path.sh--将相对路径转换为绝对路径
#
#概要
#绝对路径.sh../relative/path/to/file
echo“$(cd$(dirname$1);pwd)/$(basename$1)”
例如:
relative path: /x/y/../../a/b/z/../c/d
absolute path: /a/b/c/d
/absolute\u path.sh../styles/academy-of-management-review.csl
/Users/doej/GitHub/styles/academy-of-management-review.csl
您的“相对”路径实际上是一条绝对路径,但它不是标准形式。相对路径从不以/
开头。也许搜索“规范路径”。可能是非常好的重复。如果还提供了文件名呢。像/x/y/./../a/b/z/./c/d.txt=>/a/b/c/d.txt第一个在包含空格的路径上失败(但有趣的是,像foo;echo BAR
这样的路径并没有像我预期的那样出现错误)-1为了引起你的注意…@j_random_hacker-(1)修复;(2) 用户会收到新评论的通知,无需使用投票来引起注意:)+2:)我知道,“引起你的注意”是黄鼠狼语--“供应动机”更像是。。。我现在这样做是作为一项一般性的政策,因为我已经明确地混合了结果,不幸的是只是评论。有趣的是,如果指定的路径不存在,Cwd::abs_path
将失败。@jared beck你能证明readlink-f
做了同样的事情吗?在我的(OS X El Capitan)安装中,readlink-f
首先基本上是stat-f
,它使用指定的格式显示信息。有关有效格式的说明,请参阅“格式”部分。。可能您安装了coreutils
?目前,OS X El Capitan有一个不同的readlink命令,可以找到符号链接的实际路径,而不是将相对路径解析为绝对路径。因此,如果我们想变得可移植,看起来我们不得不更改目录,然后再返回。+1,但是您是否可以通过添加使用Cwd qw(abs_path realpath fast_abs_path)使其更完整代码>在示例之前?按原样,所有3个示例都会产生“未定义的子例程”错误。对于安装了像样的Perl但没有安装realpath的发行版,一行版本为:alias realpath=“Perl-MCwd-e”print Cwd::realpath($ARGV[0]),qq'
@olibre MacOSX,Perl v5.18.2。脚本位于:@Mark您的shell正在扩展别名定义中的$ARGV
,因此Perl可以看到Cwd::realpath([0])
,这是别名中的数组引用Escape$ARGV
。zsh没有这个问题。请参阅我的编辑,它转义了别名,应该适用于bash/zsh/ksh。
use Cwd 'realpath';
my $abs_path = realpath($file);
use Cwd 'fast_abs_path';
my $abs_path = fast_abs_path($file);
use Cwd qw(abs_path realpath fast_abs_path);
#!/bin/bash
resolve_path() {
#I'm bash only, please!
# usage: resolve_path <a file or directory>
# follows symlinks and relative paths, returns a full real path
#
local owd="$PWD"
#echo "$FUNCNAME for $1" >&2
local opath="$1"
local npath=""
local obase=$(basename "$opath")
local odir=$(dirname "$opath")
if [[ -L "$opath" ]]
then
#it's a link.
#file or directory, we want to cd into it's dir
cd $odir
#then extract where the link points.
npath=$(readlink "$obase")
#have to -L BEFORE we -f, because -f includes -L :(
if [[ -L $npath ]]
then
#the link points to another symlink, so go follow that.
resolve_path "$npath"
#and finish out early, we're done.
return $?
#done
elif [[ -f $npath ]]
#the link points to a file.
then
#get the dir for the new file
nbase=$(basename $npath)
npath=$(dirname $npath)
cd "$npath"
ndir=$(pwd -P)
retval=0
#done
elif [[ -d $npath ]]
then
#the link points to a directory.
cd "$npath"
ndir=$(pwd -P)
retval=0
#done
else
echo "$FUNCNAME: ERROR: unknown condition inside link!!" >&2
echo "opath [[ $opath ]]" >&2
echo "npath [[ $npath ]]" >&2
return 1
fi
else
if ! [[ -e "$opath" ]]
then
echo "$FUNCNAME: $opath: No such file or directory" >&2
return 1
#and break early
elif [[ -d "$opath" ]]
then
cd "$opath"
ndir=$(pwd -P)
retval=0
#done
elif [[ -f "$opath" ]]
then
cd $odir
ndir=$(pwd -P)
nbase=$(basename "$opath")
retval=0
#done
else
echo "$FUNCNAME: ERROR: unknown condition outside link!!" >&2
echo "opath [[ $opath ]]" >&2
return 1
fi
fi
#now assemble our output
echo -n "$ndir"
if [[ "x${nbase:=}" != "x" ]]
then
echo "/$nbase"
else
echo
fi
#now return to where we were
cd "$owd"
return $retval
}
%% ls -l `which mvn`
lrwxr-xr-x 1 draistrick 502 29 Dec 17 10:50 /usr/local/bin/mvn@ -> ../Cellar/maven/3.2.3/bin/mvn
%% cat test.sh
#!/bin/bash
. resolve_path.inc
echo
echo "relative symlinked path:"
which mvn
echo
echo "and the real path:"
resolve_path `which mvn`
%% test.sh
relative symlinked path:
/usr/local/bin/mvn
and the real path:
/usr/local/Cellar/maven/3.2.3/libexec/bin/mvn