shell中提取字符串子串去除文件后缀最常用可靠方式是参数扩展:${var%.*}去最短后缀(如report.txt→report),${var%%.*}去最长后缀(如archive.tar.gz→archive),需含点才匹配,无点时原样输出,可加条件判断确保安全。

Shell 中提取字符串子串以去除文件后缀名,最常用、最可靠的方式是使用参数扩展(Parameter Expansion),无需调用外部命令如 basename 或 sed,效率高且可移植性强。
用 % 去掉最短匹配的后缀(推荐)
语法:${var%.*} —— 从末尾开始,去掉第一个点及之后的内容(即最短的后缀)。
- 适用于大多数单后缀文件,如
report.txt→report - 若文件名含多个点(如
archive.tar.gz),${var%.*}只去掉.gz,结果为archive.tar - 注意:必须有
.才会匹配;若变量不含点,原样输出
用 %% 去掉最长匹配的后缀(去完整扩展名)
语法:${var%%.*} —— 从末尾开始,去掉最长的以点开头的后缀部分。
- 适合多级后缀场景,如
data.config.json→data - 对
archive.tar.gz,结果是archive - 同样要求字符串中至少有一个
.;否则不变化
安全处理:先判断是否含点再截取
避免误删无后缀的文件名(如 Makefile、README),可加条件检查:
[[ $file == *.* ]] && name=${file%.*} || name=$file- 或更简洁:
name=${file%.*}; [[ $name == $file ]] && name=$file(当没匹配到点时还原)
补充:只去已知后缀(如固定去 .log)
若需精确移除特定后缀(而非任意点后内容),可用:
${var%.log}—— 去掉结尾的.log(不带点则无效)${var%%.log}—— 同上,但用于防止误匹配(实际效果相同,因.log不含通配符)- 支持通配:
${var%.pyc?}可匹配.pyc或.pyca等(需 shell 支持扩展 glob)











