去除文件后缀有多种方式。测试驱动开发,假设我们的测试用例如下:
- 输入
index2.html输出index2 - 输入
index输出index - 输入
index-foo.html输出index-foo - 输入
foo/bar/baz/fox.html输出fox
版本 1:使用内置方法 basename
最简单是使用内置方法 basename,如果知道要去除哪种文件扩展名:
remove_known_extension() {
local name=$(basename "$1", '.html') # 提取文件名(去除路径和后缀)
echo name
}
如果无法预先知道,需分两步:
remove_extension() {
local filename=$(basename "$1") # 提取文件名(去除路径)
echo "${filename%.*}" # 去除后缀
}
如果你是前端开发者,我们还可以在 bash 中调用 node.js 来达到相同目的。
版本 2:调用 Node.js 内置模块 path
因为:
❯ node
Welcome to Node.js v16.20.2.
Type ".help" for more information.
> require('path').parse('foo/bar/baz/fox.html')
{
root: '',
dir: 'foo/bar/baz',
base: 'fox.html',
ext: '.html',
name: 'fox'
}
故:
require('path').parse('foo/bar/baz/fox.html').name
// 输出 `fox`
故:
remove_extension_use_node() {
local filename="$1"
node -e "console.log(require('path').parse('$filename').name)"
}
测试下:
# 生成 bash 字符串数组
array=("index2.html" "index" "index-foo.html" "foo/bar/baz/fox.html")
for filename in "${array[@]}"; do
echo $filename '=>' "$(remove_extension_use_node "$filename")"
done
结果:
index2.html => index2
index => index
index-foo.html => index-foo
foo/bar/baz/fox.html => fox
版本 3:调用 Node.js 使用 split
remove_extension_use_split() {
local filename="$1"
node -p "'$1'.split('/').at(-1).split('.').at(0)"
}
小技巧
node -e 可以换个 flag -p(e for evaluation and p for print)也就省去了 console.log
- node -e "console.log(require('path').parse('$filename').name)"
+ node -p "require('path').parse('$filename').name"
性能对比
# 使用 Linux 内置命令 basename 🚀
bash t.sh 0.03s user 0.17s system 60% cpu 0.328 total
# 使用 node.js path 模块 🐌
bash t.sh 0.03s user 0.62s system 76% cpu 0.854 total
# 使用 split 🐌
bash t.sh 0.00s user 0.61s system 71% cpu 0.843 total
可以看出使用 Node.js 效率最低,因为每次调用都需要新启动一个线程,当然并不意味 Node.js 一定比 shell 慢。