Bash内で使用して、OS X上のファイルへの絶対パスと正規化されたパスを見つけることができる簡単なコマンドを探しています(Linuxの「readlink-f」に似ています)。
次のサンプルbashセッションは、目的の動作を示す「abspath」という[架空の]ユーティリティについて説明しています。
$ pwd
/Users/guyfleegman
$ ls -lR
drwxr-xr-x 4 guyfleegman crew 136 Oct 30 02:09 foo
./foo:
-rw-r--r-- 1 guyfleegman crew 0 Oct 30 02:07 bar.txt
lrwxr-xr-x 1 guyfleegman crew 7 Oct 30 02:09 baz.txt -> bar.txt
$ abspath .
/Users/guyfleegman
$ abspath foo
/Users/guyfleegman/foo
$ abspath ./foo/bar.txt
/Users/guyfleegman/foo/bar.txt
$ abspath foo/baz.txt
/Users/guyfleegman/foo/baz.txt
上記の例の最後の `` abspath'`の呼び出しと同様に、シンボリックリンクを自動的に解決しないことをお勧めしますが、ここではあまりうるさくなりません。
function abspath() { pushd . > /dev/null; if [ -d "$1" ]; then cd "$1"; dirs -l +0; else cd "`dirname \"$1\"`"; cur_dir=`dirs -l +0`; if [ "$cur_dir" == "/" ]; then echo "$cur_dir`basename \"$1\"`"; else echo "$cur_dir/`basename \"$1\"`"; fi; fi; popd > /dev/null; }
例:
abspath / => /
abspath /.DS_Store => /.DS_Store
abspath ~ => /Users/mschrag
cd /tmp; abspath . => /tmp
cd /; abspath .DS_Store => /.DS_Store
これを行う組み込みコマンドはないと思います。 Jesse Wilson このためのbashスクリプトを作成しました:
#!/bin/bash
cd -P -- "$(dirname -- "$1")" &&
printf '%s\n' "$(pwd -P)/$(basename -- "$1")"
ただし、/
(印刷/etc
)などの//etc
の直下のパスや、.
と..
(印刷/cwd/.
どちらの場合も)。私はそれを変更しようとしましたが、私の不十分なbash-fuは失敗しました。
これが私の提案です:
#!/usr/bin/env python
import os.path
import sys
for arg in sys.argv[1:]:
print os.path.abspath(arg)
/usr/bin/abspath
またはそのようなものとして保存し、実行可能にします。出力例:
Servus08:~ danielbeck$ abspath .
/Users/danielbeck
Servus08:~ danielbeck$ abspath /tmp
/tmp
Servus08:~ danielbeck$ abspath Documents
/Users/danielbeck/Documents
Servus08:~ danielbeck$ abspath . /tmp Documents
/Users/danielbeck
/tmp
/Users/danielbeck/Documents
doシンボリックリンクの解決が必要な場合は、print
行を次のように変更します。
print os.path.realpath(os.path.abspath(arg))
これを取得するには:
Servus08:~ danielbeck$ abspath . /tmp Documents
/Users/danielbeck
/private/tmp
/Users/danielbeck/Documents
1つのオプションは、coreutilsをインストールして、greadlink -f
を使用することです。シンボリックリンクを解決し、存在しない場合は/Foo/
または~/foo.txt
で機能しますが、/Foo/foo.txt
が存在しない場合は/Foo/
では機能しません。
$ brew install coreutils
$ greadlink -f /etc
/private/etc
$ greadlink -f ~/Documents/
/Users/lauri/Documents
$ greadlink -f ..
/Users
$ greadlink -f //etc/..////
/private
$ greadlink -f /Foo
/Foo
$ greadlink -f /Foo/foo.txt
$
これはシンボリックリンクを解決せず、/Foo/foo.txt
でも機能しません。
abspath() {
if [ -d "$1" ]; then
( cd "$1"; dirs -l +0 )
else
( cd "$(dirname "$1")"; d=$(dirs -l +0); echo "${d%/}/${1##*/}" )
fi
}
abspath /etc # /etc
abspath ~/Foo/foo.txt # doesn't work
abspath ~/Foo # works
abspath .
abspath ./
abspath ../
abspath ..
abspath /
abspath ~
abspath ~/
abspath ~/Documents
abspath /\"\ \'
abspath /etc/../etc/
abspath /private//etc/
abspath /private//
abspath //private # //private
abspath ./aa.txt
abspath aa.tar.gz
abspath .aa.txt
abspath /.DS_Store
abspath ~/Documents/Books/
dirs -l
はチルダ拡張を実行します。 dirs +0
は、スタックに他のディレクトリがある場合、最上位のディレクトリのみを出力します。
pythonまたはRubyのいずれかでそれを行うことができると思います。
$ Ruby -e 'puts File.expand_path("~/somepath")'
またはそれをコマンドにします
#!/usr/bin/env Ruby
puts File.expand_path(ARGV[0])
Perl用にFile :: Specモジュールがインストールされている場合は、次のようにすることができます。
Perl -MFile::Spec -e 'print File::Spec->rel2abs("../however/complex/../you/want/to.get"), "\n"'
Bash/shスクリプトの場合、次の再帰関数を使用できます。
canonical_readlink ()
{
cd `dirname $1`;
__filename=`basename $1`;
if [ -h "$__filename" ]; then
canonical_readlink `readlink $__filename`;
else
echo "`pwd -P`";
fi
}
answer=$(canonical_readlink $0)
Coreutilsのインストールがオプションでない場合、以下はシンボリックリンクのコンボを処理します。および..そしてGNU realpathは次のようにファイルとフォルダーで動作します:
#!/usr/bin/env bash
realpath()
{
if ! pushd $1 &> /dev/null; then
pushd ${1##*/} &> /dev/null
echo $( pwd -P )/${1%/*}
else
pwd -P
fi
popd > /dev/null
}
ただし、realpathの--relative-toはサポートしていません。これには https://stackoverflow.com/a/12498485/869951 が必要です。
OSX用に次のライブラリをインストールします。
brew install coreutils
greadlink -f file.txt
制約がMacOS(当時はOS X)であるとすると、PHPはデフォルトで使用可能です。これにより、ファイルのルートディレクトリが返されます。ファイルを取得するにはdirname
を削除してください。 、も。
export SOURCE_DIRECTORY="$(php -r 'echo dirname(realpath($argv[1]));' -- "${BASH_SOURCE[0]}")"