问:有没有简单的sh/bash/zsh/fish/…命令打印任何文件的绝对路径我馈送它?

用例:我在目录/a/b中,我想在命令行上打印文件c的完整路径,这样我就可以轻松地将它粘贴到另一个程序:/a/b/c中。这很简单,但是在处理长路径时,一个小程序可能会为我节省5秒左右的时间。因此,让我感到惊讶的是,我找不到一个标准的实用程序来做这件事——真的没有吗?

下面是一个示例实现,abspath.py:

#!/usr/bin/python
# Author: Diggory Hardy <diggory.hardy@gmail.com>
# Licence: public domain
# Purpose: print the absolute path of all input paths

import sys
import os.path
if len(sys.argv)>1:
    for i in range(1,len(sys.argv)):
        print os.path.abspath( sys.argv[i] )
    sys.exit(0)
else:
    print >> sys.stderr, "Usage: ",sys.argv[0]," PATH."
    sys.exit(1)

当前回答

这个相对路径到绝对路径转换器的壳函数

不需要任何工具(只需要CD和pwd) 适用于目录和文件 处理. .和。 处理目录或文件名中的空格 要求文件或目录存在 如果给定路径上不存在,则返回零 将绝对路径作为输入处理(基本上是传递它们)

代码:

function abspath() {
    # generate absolute path from relative path
    # $1     : relative filename
    # return : absolute path
    if [ -d "$1" ]; then
        # dir
        (cd "$1"; pwd)
    elif [ -f "$1" ]; then
        # file
        if [[ $1 = /* ]]; then
            echo "$1"
        elif [[ $1 == */* ]]; then
            echo "$(cd "${1%/*}"; pwd)/${1##*/}"
        else
            echo "$(pwd)/$1"
        fi
    fi
}

示例:

# assume inside /parent/cur
abspath file.txt        => /parent/cur/file.txt
abspath .               => /parent/cur
abspath ..              => /parent
abspath ../dir/file.txt => /parent/dir/file.txt
abspath ../dir/../dir   => /parent/dir          # anything cd can handle
abspath doesnotexist    =>                      # empty result if file/dir does not exist
abspath /file.txt       => /file.txt            # handle absolute path input

注意:这是基于nolan6000和bsingh的答案,但修复了文件大小写。

我也理解最初的问题是关于一个现有的命令行实用程序。但由于这似乎是关于stackoverflow的问题,包括shell脚本,希望有最小的依赖关系,我把这个脚本解决方案放在这里,所以我可以稍后找到它:)

其他回答

我用单线

(cd ${FILENAME%/*}; pwd)

但是,这只能在$FILENAME有一个实际存在的任何类型的前导路径(相对或绝对)时使用。如果根本没有前导路径,那么答案就是$PWD。如果前导路径不存在,则答案可能是不确定的,否则,如果路径是绝对路径,则答案只是${FILENAME%/*}。

把这些放在一起,我建议使用下面的函数

function abspath() {
  # argument 1: file pathname (relative or absolute)
  # returns: file pathname (absolute)
  if [ "$1" == "${1##*/}" ]; then # no path at all
    echo "$PWD"
  elif [ "${1:0:1}" == "/" -a "${1/../}" == "$1" ]; then # strictly absolute path
    echo "${1%/*}"
  else # relative path (may fail if a needed folder is non-existent)
    echo "$(cd ${1%/*}; pwd)"
  fi
}

还要注意,这只适用于bash和兼容的shell。我不相信替换在简单的shell sh中起作用。

这里有一个只使用zsh的函数,我喜欢它的紧凑性。它使用了“A”扩展修饰符—参见zshexpn(1)。

realpath() { for f in "$@"; do echo ${f}(:A); done }

使用realpath

$ realpath example.txt
/home/username/example.txt

如果你没有readlink或realpath实用工具,那么你可以使用下面的函数,它可以在bash和zsh中工作(不确定其他的)。

abspath () { case "$1" in /*)printf "%s\n" "$1";; *)printf "%s\n" "$PWD/$1";; esac; }

这也适用于不存在的文件(就像python函数os.path.abspath)。

不幸的是,沐浴。/somefile不能去掉圆点。

在Ruby中获取绝对路径的另一种方法:

realpath() {ruby -e "require 'Pathname';将Pathname.new(1美元).realpath.to_s”;}

不带参数(当前文件夹)和相对和绝对文件或文件夹路径作为参数。