Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/oop/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Perl 将相对路径转换为绝对路径?_Perl_Unix_Shell_Path_Absolute Path_Bash - Fatal编程技术网

Perl 将相对路径转换为绝对路径?

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 有几点需要注意: 这还具有解析所有符号链接的副作用。这可能是可取的,也可

我不确定这些路径是否重复。给定相对路径,如何使用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
有几点需要注意:

  • 这还具有解析所有符号链接的副作用。这可能是可取的,也可能不是可取的,但通常是可取的
  • 如果引用不存在的目录,
    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