シンボリックリンクを含む可能性がある相対パスから絶対(および正規化)パスを取得するUnixコマンドはありますか?
readlink
ユーティリティを-f
オプションとともに使用できます。
-f, --canonicalize
canonicalize by following every symlink in every component of the given name recursively; all but the last component must exist
一部のディストリビューション、たとえば GNU coreutils および FreeBSD を使用するディストリビューションには、基本的に realpath(1)
を呼び出すだけのrealpath(3)
ユーティリティも付属しています とほぼ同じです。
移植性のあるように、 PWD
variable は、シェルによって現在のディレクトリの1つの絶対場所に設定されます。そのパスのどのコンポーネントもシンボリックリンクである場合があります。
case $f in
/*) absolute=$f;;
*) absolute=$PWD/$f;;
esac
.
と..
も削除したい場合は、ファイルを含むディレクトリに移動して$PWD
を取得します。
if [ -d "$f" ]; then f=$f/.; fi
absolute=$(cd "$(dirname -- "$f")"; printf %s. "$PWD")
absolute=${absolute%?}
absolute=$absolute/${f##*/}
シンボリックリンクをたどるポータブルな方法はありません。ディレクトリへのパスがある場合、ほとんどのunices $(cd -- "$dir" && pwd -P 2>/dev/null || pwd)
はシンボリックリンクを使用しないパスを提供します。これは、シンボリックリンクを追跡するシェルがpwd -P
(「物理的」)。
一部のuniceは、ファイルへの「物理」パスを出力するユーティリティを提供しています。
readlink -f
があり、FreeBSD≥8.3、NetBSD≥4.0、およびOpenBSDまでさかのぼります2.2。realpath
があります(一部のLinuxシステムにも存在し、BusyBoxにあります)。Perlが利用可能な場合は、 Cwd
module を使用できます。
Perl -MCwd -e 'print Cwd::realpath($ARGV[0])' path/to/file
pwd
はあなたのニーズに合っていますか?現在のディレクトリの絶対パスを提供します。または、多分あなたが望むのは realpath() です。
alister
およびrss67
in この記事 最も安定していて互換性があり、最も簡単な方法を紹介します。これまでより良い方法を見たことがありませんでした。
RELPATH=./../
cd $RELPATH
ABSPATH=`pwd`
元の場所に戻りたい場合は、
ORGPATH=`pwd`
RELPATH=./../
cd $RELPATH
ABSPATH=`pwd`
cd $ORGPATH
または
RELPATH=./../
cd $RELPATH
ABSPATH=`pwd`
cd -
これがお役に立てば幸いです。これは私にとって最大の解決策でした。
他のすべての人の答えを尊重して、私は以下の関数がどこでも見つけた他の関数よりも非常に簡単でLinux/MAC OSX間で移植できることを発見しました。誰かを助けるかもしれません。
#!/usr/bin/bash
get_absolute_path(){
file_path=`pwd $1`
echo "$file_path/$1"
}
#to assign to a variable
absolute_path=$(get_absolute_path "file.txt")
echo $absolute_path
ここでの他の回答は問題ありませんでしたが、私のニーズには不十分でした。どのマシンのスクリプトでも使用できるソリューションが必要でした。私の解決策は、必要な場所でスクリプトから呼び出すことができるシェルスクリプトを作成することでした。
#!/bin/sh
if [ $# -eq 0 ] || [ $# -gt 2 ]; then
printf 'Usage: respath path [working-directory]\n' >&2
exit 1
fi
cantGoUp=
path=$1
if [ $# -gt 1 ]; then
cd "$2"
fi
cwd=`pwd -P` #Use -P option to account for directories that are actually symlinks
#Handle non-relative paths, which don't need resolution
if echo "$path" | grep '^/' > /dev/null ; then
printf '%s\n' "$path"
exit 0
fi
#Resolve for each occurrence of ".." at the beginning of the given path.
#For performance, don't worry about ".." in the middle of the path.
while true
do
case "$path" in
..*)
if [ "$cwd" = '/' ]; then
printf 'Invalid relative path\n' >&2
exit 1
fi
if [ "$path" = '..' ]; then
path=
else
path=`echo "$path" | sed 's;^\.\./;;'`
fi
cwd=`dirname $cwd`
;;
*)
break
;;
esac
done
cwd=`echo "$cwd" | sed 's;/$;;'`
if [ -z "$path" ]; then
if [ -z "$cwd" ]; then
cwd='/'
fi
printf '%s\n' "$cwd"
else
printf '%s/%s\n' "$cwd" "$path"
fi
このソリューションは、移植性のためにBourne Shell用に作成されています。これは「respath.sh」という名前のスクリプトにあります。
このスクリプトは次のように使用できます。
respath.sh '/path/to/file'
またはこのように
respath.sh '/relative/path/here' '/path/to/resolve/relative/to'
スクリプトは、2番目の引数からのパスを開始点として使用して、最初の引数のパスを解決します。最初の引数のみが指定されている場合、スクリプトは現在の作業ディレクトリからの相対パスを解決します。
さらに、$1
(通常${PWD}
)の定義済みパスがいくつかある場合は、次のように機能します。
CWD="${1:-${PredefinedAbsolutePath}}"
if [ "${CWD}" != "${PredefinedAbsolutePath}}" ]; then
case $1 in
/*) echo "CWD=${CWD}"; ;;
*) CWD=$(realpath $1); echo "CWD=${CWD}"; ;;
esac
fi