You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

zsh中file2与file3输出存在差异的原因解析

zsh脚本中file2与file3输出差异的原因解析

脚本与执行结果

脚本代码:

base="/VS/Harry Potter - Hedwig's Theme (Harmonica Ver.) [w2kuM-Rp_IY].info.json"
echo "base:  $base";;
dir=$(dirname "$base");
filename=$(basename "$base");
file=${${filename%.*}%.*};
file2=${${"$(basename $filename)"%.*}%.*};
file3=${${$(basename $filename)%.*}%.*};
echo "file:  $dir/$file";;
echo "file2: $dir/$file2";;
echo "file3: $dir/$file3";;

执行输出:

(base) ➜  Youtube zsh 1.sh
base:  /VS/Harry Potter - Hedwig's Theme (Harmonica Ver.) [w2kuM-Rp_IY].info.json
file:  /VS/Harry Potter - Hedwig's Theme (Harmonica Ver.) [w2kuM-Rp_IY]
file2: /VS/Harry Potter - Hedwig's Theme (Harmonica Ver.) [w2kuM-Rp_IY]
file3: /VS/Harry Potter - Hedwig's Theme (Harmonica Ver [w2kuM-Rp_IY]

差异原因

两者的核心区别在于命令替换是否被双引号包裹,以及zsh对无引号字符串的处理逻辑:

  1. file2中,$(basename $filename)被双引号包裹,命令替换的结果会被当作单个完整字符串处理。哪怕$filename未加引号导致被分词,basename命令的输出最终被双引号整合为单一字符串,后续的%.*两次后缀截断操作都是针对整个文件名进行,因此得到正确结果。
  2. file3中,$(basename $filename)没有被双引号包裹,命令替换的输出会被zsh按空格拆分成多个独立的单词(数组元素)。此时${${...}%.*}会对数组中的每个单词单独执行后缀截断操作:
    • 原文件名中的(Harmonica Ver.)被拆分为(Harmonica和Ver.)两个元素,Ver.)里的.)会被%.*匹配并截断,变成Ver;
    • 其他不含.的单词保持不变;
    • 最后一个单词[w2kuM-Rp_IY].info.json经过两次截断后得到[w2kuM-Rp_IY];
    • 这些处理后的单词重新拼接,就得到了file3的异常输出。

简单来说,file3因为缺少双引号,导致文件名被拆分成多个部分分别处理,最终出现截断错误。

内容的提问来源于stack exchange,提问作者Icec Winter

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.14 04:27:50