2011-07-10 15 views
36

パス名の..をbashスクリプトの絶対パス名に変換する方法。つまり、私がパス/home/nohsib/dvc/../bopを持っていれば、この場合はドットが入っていないパスに変更したいです。/home/nohsib/bopパス名の ".."をbashスクリプトの絶対名に変換する方法は?

どうすればいいですか?

+2

@Tony :Re。あなたのmod: '' .. ''は省略記号ではありません。それはちょうど2つの点です... 1つの点は現在のディレクトリを意味し、2つの点は親を意味します。省略記号は、不確定な範囲を示します。 '' .. ''は非常に具体的です。 [Ellipsis(プログラミングオペレータ)](http://en.wikipedia.org/wiki/Ellipsis_%28programming_operator%29) –

+0

@fred - ありがとう、私がそこで何を考えていたかわからない。私が言うことができるのは遅すぎ、SOの質問を編集するには遅すぎるということです。私は寝る。 – Tony

+0

これはおそらくUnixのスタック交換サイトに属しています... – jth41

答えて

40

あなたが探しているもの:

ABSOLUTE_PATH=$(cd /home/nohsib/dvc/../bop; pwd) 
+2

'cdよりはるかに良い; pwd'ソリューションです。関連するC関数が 'realpath(3)'であることは注目に値する。 –

+1

これは100%ポータブルではありませんが、ほとんどのLinuxシステムで動作するはずです – Daenyth

+8

これは間違った答えです。 SOはシンボリックリンクを実際のパスに解決する必要はありませんが、相対パスをabsoluteに展開する必要はありません。私がデータファイルにアクセスしたい場合、readlinkまたはrealpathが失敗するように、シンボリックリンクへの相対パスが使用されているときにdirの絶対パスを解決したい場合、ディレクトリにスクリプトへのデータファイルとシンボリックリンクがあるとします。 –

29

試してみてください。

echo "`cd $rel_path; pwd`" 
+3

私はこの答えが一番上にあるべきだと思います。できます。 OS Xで問題のあるreadlinkソリューションとは異なり、クロスプラットフォームです。 – algal

+0

これはファイルパスではなくディレクトリパスでのみ機能します。 –

+4

@Craig: 'ABSOLUTE_PATH = $(cd $(dirname {dir or file}); pwd)' –

2

使用

echo Absolute path: $(cd $1; pwd) 
-1

(あなたの相対パスが変数$ rel_pathに保存されていると仮定して)これを試してみてくださいis readlink

absolute_path=$(readlink -m /home/nohsib/dvc/../bop) 

ご注意:あなたは "-m" オプションを提供していますGNUのreadlink実装を使用する必要があります。たとえば、BSDのreadlinkはそうではありません。

+2

pwdを実行し、その出力をキャプチャしてから、echoを使って出力しますか?いいえ、ちょうどbackticksとエコーなしでpwdを実行する(基本的にお互いをキャンセルする)。 –

1

ただ、追加のノート、あなたの現在のパスがシンボリックリンクの下にある場合、あなたはこれで本当のパス解決することができます:あなたの特定の問題を解決するために

pwd -P 

を、これはにディレクトリを変更するcdコマンドを発行します。そこに「..」のないパス。あなただけの正しいパスで、同じフォルダになります注意:

cd `pwd -P` 
0

GNUのREADLINKとのrealpathに代わるものとして、私はPWDと詰め込むような外部コマンドの独立したスクリプトで実行されているだけでなく機能を作成していました。これらの

http://www.linuxquestions.org/questions/blog/konsolebox-210384/getting-absolute-paths-of-unix-directories-and-filenames-in-shell-scripts-3956/

一つは、この一つです。絶対パスを$ __に保存します。私はパス名の拡張から安全であるためにそこに読んでいました。シェルの下

function getabspath { 
    local -a T1 T2 
    local -i I=0 
    local IFS=/ A 

    case "$1" in 
    /*) 
     read -r -a T1 <<< "$1" 
     ;; 
    *) 
     read -r -a T1 <<< "/$PWD/$1" 
     ;; 
    esac 

    T2=() 

    for A in "${T1[@]}"; do 
     case "$A" in 
     ..) 
      [[ I -ne 0 ]] && unset T2\[--I\] 
      continue 
      ;; 
     .|'') 
      continue 
      ;; 
     esac 

     T2[I++]=$A 
    done 

    case "$1" in 
    */) 
     [[ I -ne 0 ]] && __="/${T2[*]}/" || __=/ 
     ;; 
    *) 
     [[ I -ne 0 ]] && __="/${T2[*]}" || __=/. 
     ;; 
    esac 
} 
0

一つの良い解決策は次のようになります。

readlink -ev mypathname 

それが解決ドットでフルパス名を出力します。使用して

7

一つの問題:

ABSOLUTE_PATH=$(cd ${possibleDirectory}; pwd)

場合は$ {possibleDirectory}が存在しないことがあり、ABSOLUTE_PATHは、現在のディレクトリに設定されます。おそらくあなたが望んでいるか期待しているものではないでしょうか。

私はこのバージョンを使用すると、一般的に、より望ましいかもしれないと思う:

ABSOLUTE_PATH=$(cd ${possibleDirectory} && pwd)

$ {possibleDirectory}は、ディレクトリのアクセス権を逃すによる存在しないか、アクセスできません場合は、ABSOLUTE_PATHは空が含まれています文字列。

この利点は、空の文字列をテストしたり、状況に応じて自然に失敗させることができることです。 'cd'コマンドが失敗した場合、現在のディレクトリにデフォルト設定すると、予期しない悲惨な結果につながる可能性があります(例:rm -rf "$ ABSOLUTE_PATH")

+0

これは、ファイルパスではなくディレクトリパスでのみ機能します。 –

3

シンボリックリンクを使わずに実行したい場合は、オプション-srealpathを使用してみてください:

$ realpath -s /home/nohsib/dvc/../bop 
/home/nohsib/bop 

realpathと、通常はすべてが、最後のコンポーネントが存在しなければならないということ。だから、仕事をする上では、以下のすべてのファイルシステムに存在している必要があります

/home 
/home/nohsib 
/home/nohsib/dvc 

しかし、あなたは-mオプションを使用して、その要件をバイパスすることができます。

$ realpath -sm /home/nohsib/dvc/../bop 
/home/nohsib/bop 

realpathは、すべてのシステム、特に古い非Debianシステムでは利用できないことに注意してください。組み込みLinux上で働いている人々のために、残念ながらBusyboxのrealpath-sまたは-mスイッチをサポートしていません。)

関連する問題