当前位置:  开发笔记 > 编程语言 > 正文

bash/fish命令用于打印文件的绝对路径

如何解决《bash/fish命令用于打印文件的绝对路径》经验,为你挑选了10个好方法。

问题:是否有一个简单的sh/bash/zsh/fish/...命令来打印我提供的文件的绝对路径?

用例:我在目录中/a/b,我想c在命令行上打印文件的完整路径,以便我可以轻松地将其粘贴到另一个程序中:/a/b/c.简单但是一个小程序可以在处理长路径时节省大约5秒钟,这最终会增加.因此,令我惊讶的是,我无法找到标准实用程序来执行此操作 - 真的没有吗?

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

#!/usr/bin/python
# Author: Diggory Hardy 
# 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)

Benjamin Ban.. 490

试试realpath.

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

+1,非常好的程序.但请注意,它是一个外部命令(不是内置的shell),默认情况下可能不会出现在每个系统中,即您可能需要安装它.在Debian中,它位于一个具有相同名称的单独包中. (123认同)

@Dalin:尝试安装coreutils.二进制文件名为grealpath. (14认同)

我在我的路径中添加了一个`realpath`,其中包括:https://github.com/westonruter/misc-cli-tools/blob/master/realpath (5认同)

这个工具是在GNU coreutils 8.15(2012年)中引入的,所以它很新. (4认同)

如果传递的文件名不存在,则不起作用. (3认同)


Paused until.. 301

尝试readlink解决符号链接:

readlink -e /foo/bar/baz

我宁愿使用'-f'而不是'-e',以便我们可以看到不存在的文件的绝对路径. (47认同)

在我看来,`-m`是最好的选择. (13认同)

@iconoclast这些选项在OSX上不可用,并且根据BSD"readlink"联机帮助页:`只打印符号链接的目标.如果给定的参数不是符号链接,readlink将不打印任何内容并退出并显示错误`,因此readlink在OSX上不能用于此目的 (11认同)

这看起来对我来说最简单,同时也是便携式的.readlink是gnu coreutils的端口,因此它几乎可以安装在任何Linux发行版上,除了一些嵌入式发行版. (5认同)


dogbane.. 240

#! /bin/sh
echo "$(cd "$(dirname "$1")"; pwd -P)/$(basename "$1")"

到目前为止唯一的POSIX解决方案不需要您编写和编译可执行文件,因为readlink和realpath不是POSIX (29认同)

我使用`function realpath {echo $(cd $(dirname $ 1); pwd)/ $(basename $ 1); 在OS X上让自己成为一个`realpath`命令(目前接受的答案).谢谢! (21认同)

不要忘记引用所有的东西.如果你不明白为什么,试试你的程序文件`ab`(a和b之间的两个空格,SO吃其中一个). (7认同)


peterh.. 78

忘掉readlinkrealpath可能会或可能不会被你的系统上安装.

在这里扩展了dogbane的答案,它被表达为一个函数:

#!/bin/bash
get_abs_filename() {
  # $1 : relative filename
  echo "$(cd "$(dirname "$1")" && pwd)/$(basename "$1")"
}

你可以像这样使用它:

myabsfile=$(get_abs_filename "../../foo/bar/file.txt")

它是如何以及为什么有效?

该解决方案利用了这样一个事实:pwd当没有参数调用时,Bash内置命令将打印当前目录的绝对路径.

为什么我喜欢这个解决方案?

它是便携式的,不需要也不readlinkrealpath经常不上的默认安装中存在一个给定的Linux/Unix发行版.

如果dir不存在怎么办?

如上所述,如果给定的目录路径不存在,函数将失败并在stderr上打印.这可能不是你想要的.您可以扩展该功能以处理这种情况:

#!/bin/bash
get_abs_filename() {
  # $1 : relative filename
  if [ -d "$(dirname "$1")" ]; then
    echo "$(cd "$(dirname "$1")" && pwd)/$(basename "$1")"
  fi
}

现在,如果父目录不存在,它将返回一个空字符串.

你如何处理尾随'..'或'.' 输入?

嗯,在这种情况下确实给出了绝对路径,但不是最小路径.它看起来像:

/Users/bob/Documents/..

如果你想解决'..',你需要使脚本像:

get_abs_filename() {
  # $1 : relative filename
  filename=$1
  parentdir=$(dirname "${filename}")

  if [ -d "${filename}" ]; then
      echo "$(cd "${filename}" && pwd)"
  elif [ -d "${parentdir}" ]; then
    echo "$(cd "${parentdir}" && pwd)/$(basename "${filename}")"
  fi
}

我想补充一点,`realpath`来自coreutils包,它还包含诸如`who`,`touch`或`cat`等工具.它是相当标准的GNU工具集,所以你可以肯定它几乎安装在任何基于Linux的机器上.那么说,你是对的:它有2个问题:i)你可能会错过它在默认安装上非GNU unix系统(如OpenBSD)ii)这个工具是在8.15版本中引入的(所以从2012年开始它是相当新的),所以你会在长期稳定的系统(如RHEL 6)上错过它. (3认同)

@marbu realpath不存在于Ubuntu 14.04或Debian Wheezy上.随着时间的推移它可能会变得有些标准,但现在肯定不是.另请注意,OP没有提及有关linux或GNU的任何内容.Bash比这更广泛地使用. (3认同)


Flimm.. 75

$ readlink -m FILE
/path/to/FILE

这比readlink -e FILEor好realpath,因为即使文件不存在也能正常工作.



1> Benjamin Ban..:

试试realpath.

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


+1,非常好的程序.但请注意,它是一个外部命令(不是内置的shell),默认情况下可能不会出现在每个系统中,即您可能需要安装它.在Debian中,它位于一个具有相同名称的单独包中.
@Dalin:尝试安装coreutils.二进制文件名为grealpath.
我在我的路径中添加了一个`realpath`,其中包括:https://github.com/westonruter/misc-cli-tools/blob/master/realpath
这个工具是在GNU coreutils 8.15(2012年)中引入的,所以它很新.
如果传递的文件名不存在,则不起作用.

2> Paused until..:

尝试readlink解决符号链接:

readlink -e /foo/bar/baz


我宁愿使用'-f'而不是'-e',以便我们可以看到不存在的文件的绝对路径.
在我看来,`-m`是最好的选择.
@iconoclast这些选项在OSX上不可用,并且根据BSD"readlink"联机帮助页:`只打印符号链接的目标.如果给定的参数不是符号链接,readlink将不打印任何内容并退出并显示错误`,因此readlink在OSX上不能用于此目的
这看起来对我来说最简单,同时也是便携式的.readlink是gnu coreutils的端口,因此它几乎可以安装在任何Linux发行版上,除了一些嵌入式发行版.

3> dogbane..:
#! /bin/sh
echo "$(cd "$(dirname "$1")"; pwd -P)/$(basename "$1")"


到目前为止唯一的POSIX解决方案不需要您编写和编译可执行文件,因为readlink和realpath不是POSIX
我使用`function realpath {echo $(cd $(dirname $ 1); pwd)/ $(basename $ 1); 在OS X上让自己成为一个`realpath`命令(目前接受的答案).谢谢!
不要忘记引用所有的东西.如果你不明白为什么,试试你的程序文件`ab`(a和b之间的两个空格,SO吃其中一个).

4> peterh..:

忘掉readlinkrealpath可能会或可能不会被你的系统上安装.

在这里扩展了dogbane的答案,它被表达为一个函数:

#!/bin/bash
get_abs_filename() {
  # $1 : relative filename
  echo "$(cd "$(dirname "$1")" && pwd)/$(basename "$1")"
}

你可以像这样使用它:

myabsfile=$(get_abs_filename "../../foo/bar/file.txt")

它是如何以及为什么有效?

该解决方案利用了这样一个事实:pwd当没有参数调用时,Bash内置命令将打印当前目录的绝对路径.

为什么我喜欢这个解决方案?

它是便携式的,不需要也不readlinkrealpath经常不上的默认安装中存在一个给定的Linux/Unix发行版.

如果dir不存在怎么办?

如上所述,如果给定的目录路径不存在,函数将失败并在stderr上打印.这可能不是你想要的.您可以扩展该功能以处理这种情况:

#!/bin/bash
get_abs_filename() {
  # $1 : relative filename
  if [ -d "$(dirname "$1")" ]; then
    echo "$(cd "$(dirname "$1")" && pwd)/$(basename "$1")"
  fi
}

现在,如果父目录不存在,它将返回一个空字符串.

你如何处理尾随'..'或'.' 输入?

嗯,在这种情况下确实给出了绝对路径,但不是最小路径.它看起来像:

/Users/bob/Documents/..

如果你想解决'..',你需要使脚本像:

get_abs_filename() {
  # $1 : relative filename
  filename=$1
  parentdir=$(dirname "${filename}")

  if [ -d "${filename}" ]; then
      echo "$(cd "${filename}" && pwd)"
  elif [ -d "${parentdir}" ]; then
    echo "$(cd "${parentdir}" && pwd)/$(basename "${filename}")"
  fi
}


我想补充一点,`realpath`来自coreutils包,它还包含诸如`who`,`touch`或`cat`等工具.它是相当标准的GNU工具集,所以你可以肯定它几乎安装在任何基于Linux的机器上.那么说,你是对的:它有2个问题:i)你可能会错过它在默认安装上非GNU unix系统(如OpenBSD)ii)这个工具是在8.15版本中引入的(所以从2012年开始它是相当新的),所以你会在长期稳定的系统(如RHEL 6)上错过它.
@marbu realpath不存在于Ubuntu 14.04或Debian Wheezy上.随着时间的推移它可能会变得有些标准,但现在肯定不是.另请注意,OP没有提及有关linux或GNU的任何内容.Bash比这更广泛地使用.

5> Flimm..:
$ readlink -m FILE
/path/to/FILE

这比readlink -e FILEor好realpath,因为即使文件不存在也能正常工作.


@KennethHoste:小牛队不提供`-m`选项.
绝对不是在DEFAULT OSX安装中。

6> Alexander Kl..:

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

不需要实用程序(只是cdpwd)

适用于目录和文件

处理...

处理dir或文件名中的空格

要求文件或目录存在

如果给定路径上不存在任何内容,则不返回任

处理绝对路径作为输入(基本上通过它们)

码:

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脚本,我把这个脚本解决方案放在这里,所以我可以在以后找到它:)



7> lessthanidea..:

find命令可能有所帮助

find $PWD -name ex*
find $PWD -name example.log

列出当前目录中或下面的所有文件,其名称与模式匹配.如果您只获得一些结果(例如,包含少量文件的树底部附近的目录),您可以简化它

find $PWD

我在Solaris 10上使用它,它没有提到的其他实用程序.


如果你依赖`PWD`,你可以简单地使用`$ PWD/$ filename`.

8> hluk..:

如果你没有readlink或realpath实用程序,你可以使用在bash和zsh中工作的以下函数(不确定其余部分).

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

这也适用于不存在的文件(与python函数一样os.path.abspath).

不幸的abspath ./../somefile是没有摆脱点.



9> wjv..:

这是一个zsh-only函数,我喜欢它的紧凑性.它使用'A'扩展修饰符 - 参见zshexpn(1).

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



10> babou..:

一般没有这样的事情 absolute path一个文件(这个声明意味着,可能有一个以上的一般,因此使用了定冠词是不恰当的).An absolute path是从根"/"开始的任何路径,并且指定一个没有歧义的文件,独立于工作目录.(例如参见维基百科).

A relative path是从另一个目录开始解释的路径.它可能是工作目录,如果它是relative path由应用程序操纵(虽然不一定).当它在目录中的符号链接中时,通常旨在相对于该目录(尽管用户可能还有其他用途).

因此,绝对路径只是相对于根目录的路径.

路径(绝对路径或相对路径)可能包含也可能不包含符号链接.如果不是这样,它在某种程度上也不受链接结构变化的影响,但这不是必需的,甚至不是必需的.有人叫canonical path(或canonical file nameresolved path)的absolute path其中所有符号链接都得到了解决,即通过向whetever它们链接到的路径已被替换.命令realpathreadlink两者都寻找规范路径,但只有realpath一个选项来获取绝对路径而不必费心解析符号链接(以及其他几个选项来获取各种路径,绝对或相对于某个目录).

这需要几个评论:

    如果已经创建了它们应该链接到的任何内容,则只能解析符号链接,这显然并非总是如此.命令realpathreadlink有选项来解释它.

    路径上的目录以后可以成为符号链接,这意味着路径不再存在canonical.因此,概念是时间(或环境)依赖.

    即使在理想情况下,当所有符号链接都可以解析时,canonical path文件可能仍然不止一个,原因有两个:

    包含该文件的分区可能已同时(ro)挂载在几个挂载点上.

    可能存在到文件的硬链接,这意味着该文件基本上存在于几个不同的目录中.

因此,即使有更严格的定义canonical path,也可能存在一些文件的规范路径.这也意味着限定符canonical有些不足,因为它通常意味着唯一性的概念.

这扩展了对该主题的简短讨论,以回答Bash中的另一个类似问题:检索给定相对的绝对路径

我的结论是,realpath设计更好,更灵活readlink.如果没有选项返回符号链接的值readlink,则不会使用它的唯一用途realpath.


1-问题一直有效答案的事实并不意味着问题已经结束.这些问题不仅限于个人使用.实际上,有回复的徽章收集的票数超过了经过验证的答案.使用新工具,"最佳"答案可能会随着时间而改变.许多人使用通过网络搜索访问的旧答案.
推荐阅读
yzh148448
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有