相対パスを指定して絶対パスを取得するコマンドはありますか?
たとえば、$ lineにdir内の各ファイルの絶対パスを含めたい ./etc/
find ./ -type f | while read line; do
   echo $line
done相対パスを指定して絶対パスを取得するコマンドはありますか?
たとえば、$ lineにdir内の各ファイルの絶対パスを含めたい ./etc/
find ./ -type f | while read line; do
   echo $line
done回答:
使用する:
find "$(pwd)"/ -type fすべてのファイルを取得するか
echo "$(pwd)/$line"絶対パスを表示する(相対パスが重要な場合)
$(pwd)代わりに使用する理由$PWD?(はい、私pwdは組み込みであることを知っています)
                    お試しくださいrealpath。
~ $ sudo apt-get install realpath  # may already be installed
~ $ realpath .bashrc
/home/username/.bashrcシンボリックリンクの拡張を回避するには、を使用しますrealpath -s。
realpathMac(OS X 10.11 "El Capitan")では利用できないようです。:-(
                    realpathCentOS 6でも利用できないようです
                    brew install coreutilsが組み込まれますrealpath
                    realpathすでに存在しています。個別にインストールする必要はありませんでした。
                    realpathGit for Windowsで利用可能です(少なくとも私にとっては)。
                    coreutilsパッケージがインストールされている場合、通常readlink -f relative_file_nameは絶対パッケージを取得するために使用できます(すべてのシンボリックリンクが解決されています)
brew install coreutils。:しかし、実行可能ファイルはAGによって付加されるgreadlink -f relative_file_name
                    #! /bin/sh
echo "$(cd "$(dirname "$1")"; pwd)/$(basename "$1")"UPDいくつかの説明
"$1"dirname "$1"cd "$(dirname "$1")、この相対ディレクトリに移動し、pwdシェルコマンドを実行して絶対パスを取得します$(basename "$1")echoにrealpathまたはreadlink -fdo と同等ではありません。たとえば、最後のコンポーネントがシンボリックリンクであるパスでは機能しません。
                    -Pにオプションをpwdコマンド:echo "$(cd "$(dirname "$1")"; pwd -P)/$(basename "$1")"
                    価値のあるものについて、私は選ばれた答えに投票しましたが、解決策を共有したいと思いました。欠点は、それがLinuxのみであることです。スタックオーバーフローが発生する前に、OSXに相当するものを探すのに5分ほどかかりました。確かにあると思います。
Linuxではreadlink -e、と組み合わせて使用できますdirname。
$(dirname $(readlink -e ../../../../etc/passwd))収量
/etc/次にdirname、の姉妹を使用してbasename、ファイル名を取得します
$(basename ../../../../../passwd)収量
passwd全部まとめて
F=../../../../../etc/passwd
echo "$(dirname $(readlink -e $F))/$(basename $F)"収量
/etc/passwdディレクトリをターゲットにしている場合は安全であり、basename何も返さず、最終出力に2つのスラッシュが含まれるだけです。
dirname、readlinkとbasename。これにより、ターゲットではなく、シンボリックリンクの絶対パスを取得することができました。
                    /home/GKFXとtouch newfile入力した場合、Enterキーを押す前に、「create / home / GKFX / newfile」を意味することを理解できます。これは、まだ存在しないファイルへの絶対パスです。
                    これが最もポータブルだと思います:
abspath() {                                               
    cd "$(dirname "$1")"
    printf "%s/%s\n" "$(pwd)" "$(basename "$1")"
    cd "$OLDPWD"
}パスが存在しない場合は失敗します。
dirname、GNUコアユーティリティであり、私が信じているすべてのunixenに共通するわけではありません。
                    dirnameはPOSIX標準ユーティリティです。ここを参照してください:pubs.opengroup.org/onlinepubs/9699919799/utilities/dirname.html
                    ${1##*/}1日間使用するバージョンを修正しようとしていましたが、そのゴミを置き換えたのでbasename "$1"、最後に/で終わるパスを適切に処理しているようです。
                    ../..
                    realpath おそらく最高です
だが ...
最初の質問は、最初は非常に混乱していましたが、前述のように、質問との関連性が低い例がありました。
選択された回答は実際には与えられた例に回答し、タイトルの質問にはまったく回答しません。最初のコマンドはその答えです(それは本当ですか?疑問です)。 '/'がなくても同じことができます。そして、2番目のコマンドが何をしているのかわかりません。
いくつかの問題が混在しています:
相対パス名を絶対パス名に変更します。それが何を示していても、おそらく何もしません。(通常、などのコマンドを発行する場合、ファイルが実際に作成される前touch foo/barに、パス名foo/barが存在し、計算で使用される可能性があります。)
特にパス上のシンボリックリンク(シンボリックリンク)が原因で、同じファイル(または潜在的なファイル)を示すいくつかの絶対パス名が存在する可能性がありますが、他の理由(デバイスが読み取り専用として2倍にマウントされている可能性があります)。そのようなシンボリックリンクを明示的に解決したい場合とそうでない場合があります。
非シンボリックファイルまたは名前へのシンボリックリンクのチェーンの最後に到達する。これにより、絶対パス名が生成される場合と生成されない場合があります。そして、それを絶対パス名に解決したい場合とそうでない場合があります。
readlink fooオプションのないコマンドfooは、その引数がシンボリックリンクであり、その回答がそのシンボリックリンクの値である場合にのみ回答を提供します。他のリンクはたどられません。答えは相対パスかもしれません:symlink引数の値は何でも。
ただし、readlinkすべてのファイルで機能するオプション(-f -eまたは-m)があり、実際に引数で示されるファイルに1つの絶対パス名(シンボリックリンクのないもの)を指定します。
これは、シンボリックリンクでないものには問題なく機能しますが、パスの中間シンボリックリンクを解決せずに絶対パス名を使用したい場合があります。これはコマンドによって行われますrealpath -s foo
シンボリックリンク引数の場合readlink、そのオプションを使用すると、引数への絶対パス上のすべてのシンボリックリンクが再度解決されますが、引数値の後に発生する可能性のあるすべてのシンボリックリンクも含まれます。引数のリンク先ではなく、引数のシンボリックリンク自体への絶対パスが必要な場合は、そうしたくないかもしれません。ここでも、fooシンボリックリンクの場合realpath -s foo、引数として指定されたものを含め、シンボリックリンクを解決せずに絶対パスを取得します。
なければ-sオプション、realpathほとんどのように同じことを
 readlink単にリンクの価値だけでなく、いくつかの他のものを読んだ以外、。なぜreadlinkそのオプションがあり、明らかにで望ましくない冗長性が生じるの
 か、私にははっきりしませんrealpath。
システムを横断していくつかのバリエーションがあるかもしれないことを除いて、ウェブを探索することはそれほど多くを語りません。
結論:realpath少なくともここで要求された用途に対して、最も柔軟性が高く、使用するのに最適なコマンドです。
他のユーティリティ(coreutilsパッケージ)の存在を示唆していないため、私のお気に入りのソリューションは@EugenKonkovによるものでした。
しかし、相対パス "。"は失敗しました。および「..」なので、これらの特殊なケースを処理するわずかに改善されたバージョンを次に示します。
cdただし、ユーザーが相対パスの親ディレクトリにアクセスする権限を持っていない場合でも、失敗します。
#! /bin/sh
# Takes a path argument and returns it as an absolute path. 
# No-op if the path is already absolute.
function to-abs-path {
    local target="$1"
    if [ "$target" == "." ]; then
        echo "$(pwd)"
    elif [ "$target" == ".." ]; then
        echo "$(dirname "$(pwd)")"
    else
        echo "$(cd "$(dirname "$1")"; pwd)/$(basename "$1")"
    fi
}オイゲンの答えは私にとってはうまくいきませんでしたが、これはうまくいきました:
    absolute="$(cd $(dirname \"$file\"); pwd)/$(basename \"$file\")"ちなみに、現在の作業ディレクトリは影響を受けません。
最善の解決策であるimhoは、https://stackoverflow.com/a/3373298/9724628に投稿されているものです。
動作にはpythonが必要ですが、エッジケースのすべてまたはほとんどをカバーしており、非常に移植可能なソリューションであるようです。
python -c "import os,sys; print(os.path.realpath(sys.argv[1]))" path/to/filepython -c "import os,sys; print(os.path.abspath(sys.argv[1]))" path/to/filerealpathが存在せず、readlinkが絶対パスを出力できないMac OS Xでbashを使用している場合は、独自のバージョンをコード化して出力することができます。これが私の実装です:
(ピュアバッシュ)
abspath(){
  local thePath
  if [[ ! "$1" =~ ^/ ]];then
    thePath="$PWD/$1"
  else
    thePath="$1"
  fi
  echo "$thePath"|(
  IFS=/
  read -a parr
  declare -a outp
  for i in "${parr[@]}";do
    case "$i" in
    ''|.) continue ;;
    ..)
      len=${#outp[@]}
      if ((len==0));then
        continue
      else
        unset outp[$((len-1))] 
      fi
      ;;
    *)
      len=${#outp[@]}
      outp[$len]="$i"
      ;;
    esac
  done
  echo /"${outp[*]}"
)
}(gawkを使用)
abspath_gawk() {
    if [[ -n "$1" ]];then
        echo $1|gawk '{
            if(substr($0,1,1) != "/"){
                path = ENVIRON["PWD"]"/"$0
            } else path = $0
            split(path, a, "/")
            n = asorti(a, b,"@ind_num_asc")
            for(i in a){
                if(a[i]=="" || a[i]=="."){
                    delete a[i]
                }
            }
            n = asorti(a, b, "@ind_num_asc")
            m = 0
            while(m!=n){
                m = n
                for(i=1;i<=n;i++){
                    if(a[b[i]]==".."){
                        if(b[i-1] in a){
                            delete a[b[i-1]]
                            delete a[b[i]]
                            n = asorti(a, b, "@ind_num_asc")
                            break
                        } else exit 1
                    }
                }
            }
            n = asorti(a, b, "@ind_num_asc")
            if(n==0){
                printf "/"
            } else {
                for(i=1;i<=n;i++){
                    printf "/"a[b[i]]
                }
            }
        }'
    fi
}(純粋なbsd awk)
#!/usr/bin/env awk -f
function abspath(path,    i,j,n,a,b,back,out){
  if(substr(path,1,1) != "/"){
    path = ENVIRON["PWD"]"/"path
  }
  split(path, a, "/")
  n = length(a)
  for(i=1;i<=n;i++){
    if(a[i]==""||a[i]=="."){
      continue
    }
    a[++j]=a[i]
  }
  for(i=j+1;i<=n;i++){
    delete a[i]
  }
  j=0
  for(i=length(a);i>=1;i--){
    if(back==0){
      if(a[i]==".."){
        back++
        continue
      } else {
        b[++j]=a[i]
      }
    } else {
      if(a[i]==".."){
        back++
        continue
      } else {
        back--
        continue
      }
    }
  }
  if(length(b)==0){
    return "/"
  } else {
    for(i=length(b);i>=1;i--){
      out=out"/"b[i]
    }
    return out
  }
}
BEGIN{
  if(ARGC>1){
    for(k=1;k<ARGC;k++){
      print abspath(ARGV[k])
    }
    exit
  }
}
{
  print abspath($0)
}例:
$ abspath I/am/.//..//the/./god/../of///.././war
/Users/leon/I/the/war相対パスがディレクトリパスである場合、私のものを試してください、最も良いはずです:
absPath=$(pushd ../SOME_RELATIVE_PATH_TO_Directory > /dev/null && pwd && popd > /dev/null)
echo $absPathecho "mydir/doc/ mydir/usoe ./mydir/usm" |  awk '{ split($0,array," "); for(i in array){ system("cd "array[i]" && echo $PWD") } }'@ ernest-aのかなり良いバージョンの改善:
absolute_path() {
    cd "$(dirname "$1")"
    case $(basename $1) in
        ..) echo "$(dirname $(pwd))";;
        .)  echo "$(pwd)";;
        *)  echo "$(pwd)/$(basename $1)";;
    esac
}正しくパスの最後の要素がある場合と、この取引..その場合には、"$(pwd)/$(basename "$1")"中@アーネスト-Aの答えのように通ってくるだろうaccurate_sub_path/spurious_subdirectory/..。
これは、他のすべてからのチェーンソリューションです。たとえば、realpathインストールされていないか、エラーコードで終了したために失敗した場合、パスが正しくなるまで次のソリューションが試行されます。
#!/bin/bash
function getabsolutepath() {
    local target;
    local changedir;
    local basedir;
    local firstattempt;
    target="${1}";
    if [ "$target" == "." ];
    then
        printf "%s" "$(pwd)";
    elif [ "$target" == ".." ];
    then
        printf "%s" "$(dirname "$(pwd)")";
    else
        changedir="$(dirname "${target}")" && basedir="$(basename "${target}")" && firstattempt="$(cd "${changedir}" && pwd)" && printf "%s/%s" "${firstattempt}" "${basedir}" && return 0;
        firstattempt="$(readlink -f "${target}")" && printf "%s" "${firstattempt}" && return 0;
        firstattempt="$(realpath "${target}")" && printf "%s" "${firstattempt}" && return 0;
        # If everything fails... TRHOW PYTHON ON IT!!!
        local fullpath;
        local pythoninterpreter;
        local pythonexecutables;
        local pythonlocations;
        pythoninterpreter="python";
        declare -a pythonlocations=("/usr/bin" "/bin");
        declare -a pythonexecutables=("python" "python2" "python3");
        for path in "${pythonlocations[@]}";
        do
            for executable in "${pythonexecutables[@]}";
            do
                fullpath="${path}/${executable}";
                if [[ -f "${fullpath}" ]];
                then
                    # printf "Found ${fullpath}\\n";
                    pythoninterpreter="${fullpath}";
                    break;
                fi;
            done;
            if [[ "${pythoninterpreter}" != "python" ]];
            then
                # printf "Breaking... ${pythoninterpreter}\\n"
                break;
            fi;
        done;
        firstattempt="$(${pythoninterpreter} -c "import os, sys; print( os.path.abspath( sys.argv[1] ) );" "${target}")" && printf "%s" "${firstattempt}" && return 0;
        # printf "Error: Could not determine the absolute path!\\n";
        return 1;
    fi
}
printf "\\nResults:\\n%s\\nExit: %s\\n" "$(getabsolutepath "./asdfasdf/ asdfasdf")" "${?}"相対パス$ lineにbash文字列置換を使用できます。
line=$(echo ${line/#..\//`cd ..; pwd`\/})
line=$(echo ${line/#.\//`pwd`\/})
echo $line基本的な文字列前置置換は、
$ {string /#substring / replacement}の公式に従います。
 
これは、ここで詳しく説明されています。https://www.tldp.org/LDP/abs/html/string-manipulation.html
\文字は否定し/、我々はそれが我々が検索/置換する文字列の一部になりたいとき。
Mac OS Catalina、Ubuntu 16、Centos 7の間で適切に移植できるソリューションを見つけることができなかったので、Pythonインラインで実行することを決定し、私のbashスクリプトでうまく機能しました。
to_abs_path() {
  python -c "import os; print os.path.abspath('$1')"
}
to_abs_path "/some_path/../secrets"