如何获取复杂文件的基名

如何获取复杂文件的基名

这是文件路径的示例:

/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如果设置正确,您不必担心变量评估会被耗尽。您甚至可以利用它来发挥自己的优势。

相关内容