Board logo

标题: [注册表类] [已解决]cmd做了reg右键改后缀名,如何兼容含空格的文件名? [打印本页]

作者: lforl    时间: 2023-12-7 13:04     标题: [已解决]cmd做了reg右键改后缀名,如何兼容含空格的文件名?

本帖最后由 lforl 于 2023-12-7 19:17 编辑

做了一个写入reg运行的右键菜单。
目标:右击zip自动改后缀名。
问题:目前只对不含空格的文件有效,对于含空格的文件不生效。疑惑的是,我明明加上引号了,还是没法对有空格的文件名改后缀名成功。
请教大佬,如何使它能兼容含空格的文件名
  1. Windows Registry Editor Version 5.00
  2. ;************************添加文件夹右键zip→7z功能*************************
  3. [HKEY_CLASSES_ROOT\.zip]
  4. @="CompressedFolder"
  5. [HKEY_CLASSES_ROOT\.zip\CompressedFolder]
  6. [HKEY_CLASSES_ROOT\.zip\CompressedFolder\ShellNew]
  7. "Data"=hex:50,4b,03,04
  8. [HKEY_CLASSES_ROOT\.zip\ShellNew]
  9. "Data"=hex:50,4b,03,04
  10. [HKEY_CLASSES_ROOT\SystemFileAssociations\.zip\Shell]
  11. [HKEY_CLASSES_ROOT\SystemFileAssociations\.zip\Shell\ChangeTo7z]
  12. @="改后缀名zip→7z(&Z)"
  13. [HKEY_CLASSES_ROOT\SystemFileAssociations\.zip\Shell\ChangeToUVZ\Command]
  14. @="cmd /c for %%I in (\"%1\") do ren \"%%I\" \"%%~nI.7z\"& exit"
复制代码

作者: 77七    时间: 2023-12-7 14:57

  1. @="cmd /c for /f \"delims=\" %%I in (\"%1\") do ren \"%%~I\" \"%%~nI.7z\"&exit"
复制代码

作者: lforl    时间: 2023-12-7 19:17

本帖最后由 lforl 于 2023-12-7 19:18 编辑

回复 2# 77七

领教了,非常完美,深表感谢!


扩展说明,以让后来者轻松了解。
delims=是for /f命令中的字符分切的开关,如果=号后面为空,就意味着不分切;如果指定字符,就意味着以那指定字符作为分切。

在 CMD 的 for /F 命令中,delims= 选项用于指定分隔符。分隔符是用于将文本行分割成多个部分(或“令牌”)的字符。
通过 delims= 选项,你可以指定一个或多个自定义分隔符。例如:
delims=, 会使用逗号作为分隔符。
delims=; 会使用分号作为分隔符。
delims=,; 会同时使用逗号和分号作为分隔符。
如果你设置 delims= 但后面没有跟任何字符(即 delims= 后面为空),这意味着整行都被视为一个单独的令牌,不进行任何分割。

参考:
CMD的for /F 的delims=选项
https://zhuanlan.zhihu.com/p/645244411?utm_id=0

【CMD】批处理 For 语句从入门到精通(完整版)_20101225
https://blog.csdn.net/qq_43155814/article/details/129780068
作者: ShowCode    时间: 2023-12-8 09:47

回复 3# lforl


    CSDN是从这里抄的 http://bbs.bathome.net/thread-2189-1-1.html
作者: lforl    时间: 2024-6-3 12:48

回复 2# 77七


   我发现在这案例中,也可以不用delims=。
直接在我的原来基础上,%%I加一个~符合,写成%%~I就完美解决了。
  1. Windows Registry Editor Version 5.00
  2. ;************************添加文件夹右键zip→7z功能*************************
  3. [HKEY_CLASSES_ROOT\.zip]
  4. @="CompressedFolder"
  5. [HKEY_CLASSES_ROOT\.zip\CompressedFolder]
  6. [HKEY_CLASSES_ROOT\.zip\CompressedFolder\ShellNew]
  7. "Data"=hex:50,4b,03,04
  8. [HKEY_CLASSES_ROOT\.zip\ShellNew]
  9. "Data"=hex:50,4b,03,04
  10. [HKEY_CLASSES_ROOT\SystemFileAssociations\.zip\Shell]
  11. [HKEY_CLASSES_ROOT\SystemFileAssociations\.zip\Shell\ChangeTo7z]
  12. @="改后缀名zip→7z(&Z)"
  13. [HKEY_CLASSES_ROOT\SystemFileAssociations\.zip\Shell\ChangeToUVZ\Command]
  14. @="cmd /c for %%I in (\"%1\") do ren \"%%~I\" \"%%~nI.7z\"& exit"
复制代码
批处理常用符号详解提到但是说的不是很深入。
期待大佬路过解释。
作者: buyiyang    时间: 2024-6-3 14:15

你一楼代码实际执行的是:
  1. "cmd.exe" /c for %I in ("文件名.zip") do ren "%I" "%~nI.7z"
  2. ren ""文件名.zip"" "文件名.7z"
复制代码
若文件名没有空格(%I本身有一对引号):ren ""文件名.zip"" "文件名.7z"
过滤掉两对引号的空字串:将 文件名.zip 重命名为 文件名.7z(没有问题)

若文件名有空格:ren ""文 件名.zip"" "文件名.7z"
过滤掉两对引号的空字串(空格为分隔符):将 文 重命名为 件名.zip 并多一个参数 文件名.7z(此命令语法不正确)

%~I 的 ~ 是去掉变量的外侧一对引号,当文件名有空格时:ren "文 件名.zip" "文件名.7z"(空格被引号转移,命令正确)
作者: 77七    时间: 2024-6-6 16:41

针对此例,%1在注册表中来说,我测试了一次含有空格的文件名,%1结果无引号,此时,用两种方法都对。
扩展到写其它脚本时,如果不知道一个变量首尾是否含有引号,而希望获取到的结果是 首尾不包含引号。
测试
  1. @echo off
  2. set str="1 23.txt"
  3. echo [%str%]
  4. for %%a in ("%str%") do echo %%~a
  5. for /f "delims=" %%a in ("%str%") do echo %%~a
  6. pause
复制代码


结果
  1. 结果
  2. ["1 23.txt"]
  3. "1
  4. 23.txt""
  5. 1 23.txt
复制代码


从结果可以看出, for %%a 获取结果不符合预期,for /f 获取结果符合预期。


好奇再测试一下,如果 变量只含有单侧引号,结果是什么样子的呢?
测试
  1. @echo off
  2. setlocal enabledelayedexpansion
  3. set "str="1 23.txt"
  4. echo [!str!]
  5. for %%a in ("!str!") do echo %%~a
  6. for /f "delims=" %%a in ("!str!") do echo %%~a
  7. pause
复制代码



结果
  1. ["1 23.txt]
  2. "1
  3. 23.txt"
  4. 1 23.txt
复制代码


同样,for /f 也能正确获取符合预期的结果,仅字符串首部 含有引号也能成功去除。
至于仅字符串尾部含有引号,结果是什么样子的呢?可以自己动手测试一下。如果尾部引号比首部多,是不是可以给首部多添加引号,然后多次for /f 扩展%%a到%%~a,获取到期望的结果呢。




欢迎光临 批处理之家 (http://www.bathome.net/) Powered by Discuz! 7.2