複雑なファイルの基本名を取得する方法

複雑なファイルの基本名を取得する方法

以下はファイルパスの例です。

/isf/GCM/VPfig/Aas/AR/ClCo el Doma Republic/VMN CRTro.txt

私が得たいのはファイルのデフォルト名です。

VMN CRTro.txt

だから私は次を試してみます。

echo /isf/GCM/VPfig/Aas/AR/ClCo el Doma Republic/VMN CRTro.txt | sed s'/\// /g' | awk '{print $NF}'
CRTro.txt     <-- not as expected

または

basename  /isf/GCM/VPfig/Aas/AR/ClCo el Doma Republic/VMN CRTro.txt
basename: extra operand `Doma'
Try `basename --help' for more information.     <-- basename cant handle spaces 

空白のあるファイルのデフォルト名を取得する最良の方法は何ですか?

答え1

あなたの道を引用してください。

basename  "/isf/GCM/VPfig/Aas/AR/ClCo el Doma Republic/VMN CRTro.txt"

答え2

問題の核心は引用です。引用符がない場合は、ファイル名がとして扱われますbasename
パスが変数ではなくハードセットの場合、robの答えは問題ありません。しかし、これが変数が使用されるスクリプトの一部である場合、2つの良い解決策があります。

$ filepath="/isf/GCM/VPfig/Aas/AR/ClCo el Doma Republic/VMN CRTro.txt"
$ basename "$filepath"
VMN CRTro.txt

しかし、basenameこれは外部ユーティリティであり、bashの一部ではありません。 bashには別のソリューションが組み込まれています。

$ filepath="/isf/GCM/VPfig/Aas/AR/ClCo el Doma Republic/VMN CRTro.txt"
$ echo "${filepath##*/}"
VMN CRTro.txt

bashにできるだけ多くの文字に一致する${filepath##*/}globを実行し、aを削除するように指示します。*//

答え3

ここの両方の答えは適切です。私は個人的にPatrickが提案したように使用したいと思います${var##*/}。しかし、ただの楽しみのために:

IFS=/ ; set -f
set -- ${0+/isf/GCM/VPfig/Aas/AR/ClCo el Doma Republic/VMN CRTro.txt}
for p do i=$((i+1))
    printf "arg#$i:\t%s\n" "${p:-/}"
done
echo now shift out...
shift $(($#-1))
printf 'arg#1:\t%s\n' "$1"

出力

arg#1:  /
arg#2:  isf
arg#3:  GCM
arg#4:  VPfig
arg#5:  Aas
arg#6:  AR
arg#7:  ClCo el Doma Republic
arg#8:  VMN CRTro.txt
now shift out...
arg#1:  VMN CRTro.txt

$IFS正しく設定すれば、変数評価が使い果たされるか心配する必要はありません。あなたはそれを有利に使用することができます。

関連情報