是否有一个命令来检索给定相对路径的绝对路径?

例如,我想要$line包含dir ./etc/中每个文件的绝对路径

find ./ -type f | while read line; do
   echo $line
done

当前回答

我发现Eugen Konkov的答案是最好的,因为它不需要安装任何程序。但是,对于不存在的目录,它将失败。

我写了一个函数,适用于不存在的目录:

function getRealPath()
{
    local -i traversals=0
    currentDir="$1"
    basename=''
    while :; do
        [[ "$currentDir" == '.' ]] && { echo "$1"; return 1; }
        [[ $traversals -eq 0 ]] && pwd=$(cd "$currentDir" 2>&1 && pwd) && { echo "$pwd/$basename"; return 0; }
        currentBasename="$(basename "$currentDir")"
        currentDir="$(dirname "$currentDir")"
        [[ "$currentBasename" == '..' ]] && (( ++traversals )) || { [[ traversals -gt 0 ]] && (( traversals-- )) || basename="$currentBasename/$basename"; }
    done
}

它通过使用dirname向上遍历直到cd成功,然后返回当前目录加上dirname删除的所有内容来解决不存在目录的问题。

其他回答

更新之前的答案使用python 3

to_abs_path() {
  python -c "import os; print (os.path.abspath('$1'))"
}

允许

to_abs_path "./../some_file.txt"

类似于@ernest-a的答案,但不影响$OLDPWD或定义一个新函数,您可以触发一个子shell (cd <path>;pwd)

$ pwd
/etc/apache2
$ cd ../cups 
$ cd -
/etc/apache2
$ (cd ~/..; pwd)
/Users
$ cd -
/etc/cups

在find的情况下,可能最简单的是给它搜索的绝对路径,例如:

find /etc
find `pwd`/subdir_of_current_dir/ -type f
echo "mydir/doc/ mydir/usoe ./mydir/usm" |  awk '{ split($0,array," "); for(i in array){ system("cd "array[i]" && echo $PWD") } }'

基于@EugenKonkov的回答和@HashChange的回答,我的回答结合了前者的简洁和对。和. .关于后者。我相信下面所有的选项仅仅依赖于基本的Shell命令语言POSIX标准。

使用dirname和basename,一个选项是:

absPathDirname()
{
    [ -d "${1}" ] && set -- "${1}" || set -- "`dirname "${1}"`" "/`basename "${1}"`"
    echo "`cd "${1}"; pwd`${2}";
}

不使用dirname或basename,另一个简单的选项是:

absPathMinusD()
{
    [ -d "${1}" ] && set -- "${1}" || set -- "${1%${1##*/}}" "/${1##*/}"
    echo "`cd "${1:-.}"; pwd`${2}";
}

我会推荐上面两个选择中的一个,其他的只是为了好玩…

Grep版本:

absPathGrep()
{
    echo "`[ "${1##/*}" ] && echo "$1" | grep -Eo '^(.*/)?\.\.($|/)' | { read d && cd "$d"; echo "${PWD}/${1#$d}"; } || echo "$1"`"
}

作为一个有趣的“可以用shell有限的RegEx做什么”的例子:

absPathShellReplace()
{
    E="${1##*/}"; D="${E#$E${E#.}}"; DD="${D#$D${D#..}}"
    DIR="${1%$E}${E#$DD}"; FILE="${1#$DIR}"; SEP=${FILE:+/}
    echo "`cd "${DIR:-.}"; pwd`${SEP#$DIR}$FILE"
}