这是文件路径的示例:
/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 的答案就很好。但如果这是脚本的一部分,其中使用了变量,那么您有两个好的解决方案:
$ 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
告诉${filepath##*/}
bash 执行 glob */
,它匹配尽可能多的字符,后跟 a /
,然后将其删除。
答案3
这里的两个答案都绰绰有余——尽管我个人会按照帕特里克的建议去做并使用${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
如果设置正确,您不必担心变量评估会被耗尽。您甚至可以利用它来发挥自己的优势。