相対パスを正規化する移植可能で便利な方法はありますか?

相対パスを正規化する移植可能で便利な方法はありますか?

ここで、「正規化」とは、基本的にファイルパスを最も単純な形式または「正規」形式に変換するプロセスを意味します。たとえば、の正式な形式/foo/.//bar/../baz/はです/foo/baz

絶対パスの場合、zshの:a修飾子は次のようなことをうまく行います。

% printf -- '%s\n%s\n' "${WILDABSPATH}" "${WILDABSPATH:a}"
/foo/.//bar/../baz/
/foo/baz

残念ながら、相対ファイルパスの場合、:a修飾子はファイルパスを絶対パスに変換するため、あまりにも多くの操作を実行します。

% printf -- '%s\n%s\n' "${WILDRELPATH}" "${WILDRELPATH:a}"
./foo/.//bar/../baz/
/tmp/foo/baz

${WILDRELPATH}最後の例を使ってに変換する良い方法はありますかfoo/baz


私の質問に対する答えの1つは次のようになります。

[[ ${ORIGINAL} == /* ]] \
  && CANONICAL=${ORIGINAL:a} \
  || CANONICAL=${${ORIGINAL:a}#$PWD/}

もっと簡単なことがありますか?

答え1

私はこの問題を使用して解決できると信じていますrealpath

次のことができます。

realpath -m --relative-to=./ ./foo/.//bar/../baz/ # Outputs foo/baz
# or
realpath -m /foo/.//bar/../baz/ # Outputs /foo/baz

関連情報