路径名中的文件名,不包括(未知)扩展名

路径名中的文件名,不包括(未知)扩展名

有一个路径名可以提取它的文件名,不包括其先验已知扩展名,具有基本名称

$ pathname="/home/paulo/paulo.pdf"
$ printf "%s\n" "$(basename $pathname .pdf)"
paulo

但如果不知道扩展名,该如何做呢?

答案1

zsh外壳中:

$ pathname=/home/paulo/paulo.pdf
$ printf '%s\n' $pathname:t:r
paulo
  • 修饰符:t(“tail”)提取最后一个路径名组件$pathname(其工作方式类似于basename)。
  • 修饰符:r(我想是“root”)提取文件名中一直到扩展名的位(如果有的话)。扩展名是文件名中最后一个点之后的部分。这意味着您将得到诸如.zshrc.

其他相关修饰符是

  • :h(“head”),其工作方式类似于dirname, 和
  • :e(“扩展名”),仅提取扩展名。

答案2

您可以使用shell 的参数扩展修饰符

$ pathname="/home/paulo/paulo.pdf"
$ filename=${pathname##*/}
$ printf "%s\n" "$filename"
paulo.pdf
$ basename=${filename%.*}
$ printf "%s\n" "$basename"
paulo

${pathname##*/}扩展为 的内容pathname,减去最长匹配的前缀*/IE完整路径(如果有)。${filename%.*}扩展为 的内容filename,减去最短后缀匹配.*IE文件的扩展名(如果有)。

请注意,这只会删除由点引入的最后一个文件名部分;所以paulo.tar.gz才会变成paulo.tar,不是paulo。严格来说,扩展名是.gz(它是一个压缩文件,恰好是一个 tarball;.tar只有在文件被提取后,扩展名才变得真正有意义)。

对于无扩展名的点文件,这也无法正常工作,例如 .bashrc或者.zshrc;basename最终变成空的。可以使用默认值来处理:

$ pathname="/home/paulo/.zshrc"
$ filename=${pathname##*/}
$ printf "%s\n" "$filename"
.zshrc
$ basename=${filename%.*}
$ printf "%s\n" "$basename"

$ printf "%s\n" "${basename:-$filename}"
.zshrc

答案3

这应该做你想要的:

pathname="/home/paulo/paulo.pdf"
printf "%s\n" "$(basename $pathname)" | sed "s/\..*$//"

相关内容