【问题标题】:Convert long filename to short filename (8.3) using cmd.exe使用 cmd.exe 将长文件名转换为短文件名 (8.3)
【发布时间】:2012-04-30 21:54:02
【问题描述】:

我正在尝试在 Windows 上将长文件名转换为短文件名 (8.3)。

带有命令行参数的批处理文件按预期工作:

short.bat

@echo OFF
echo %~s1

调用short.bat C:\Documents and Settings\User\NTUSER.DAT 返回C:\DOCUM~1\USER\NTUSER.DAT

但是,我不喜欢为此使用额外的 .bat 文件。我宁愿用 ruby​​ 脚本中的整个命令调用cmd.exe。 我该怎么做?

作为中间步骤,我尝试对批处理文件中的路径进行硬编码,但这不起作用:

short1.bat

@echo OFF
SET filename="C:\Documents and Settings\User\NTUSER.DAT"
echo %filename%
echo %~sfilename%

echo %filename% 有效,但echo %~sfilename% 给出以下错误:

The following usage of the path operator in batch-parameter
substitution is invalid: %~sfilename%

For valid formats type CALL /? or FOR /?

如果 short1.bat 有效,我如何将其转换为可以使用 cmd.exe \c ... 调用的单行代码?

还有一个问题 (how to get DOS path instead of Windows path),不过是专门询问当前目录的路径。

【问题讨论】:

  • 我没有立即使用 Windows,但请尝试 %filename:~s%(类似于子字符串表示法的样式,%filename:~0,1%)。如果可行,我会给出答案。
  • @ChrisMorgan - 绝对不是。行不通。
  • @dbenham:不是吗?呃,好吧。值得一试。
  • 为什么还需要短名称?这是遗留功能,除非绝对必要,否则最好避免使用。
  • @dbenham - 长文件名必须用引号括起来,这可能很难传递到 psexec 等常见例程中 - 请参阅 stackoverflow.com/questions/24905546/…

标签: windows batch-file command-line long-filenames short-filenames


【解决方案1】:
cmd /c for %A in ("C:\Documents and Settings\User\NTUSER.DAT") do @echo %~sA

【讨论】:

  • 这适用于我的本地驱动器,但不适用于映射的网络驱动器。有什么想法吗?
  • @user1251007 - 您使用的是什么版本的 Windows?存在一个处理 8.3 名称和 ~s 修饰符的已知 XP 错误:stackoverflow.com/questions/8354305/…
  • @user1251007 - 此外,管理员可以为给定的驱动器禁用 8.3 文件名的生成。您能否验证 DIR /X 是否在您的网络驱动器上提供了短文件名?
  • @user1251007 - 我相当肯定你被卡住了,除非你可以让你的管理员在你的网络驱动器上启用短文件名。但短名称可能因某种原因被禁用。
  • @AKhudairy - 这个问题专门针对使用cmd /c 的命令行解决方案。在批处理文件中,您必须将所有百分比加倍 - 您只需要 for %%A in ("some path here\some file.ext") do echo %%~sA
【解决方案2】:

将 filename.txt 替换为你要转换为 8.3 的文件名

dir /x filename.txt

然后,您必须使用空格作为分隔符(正则表达式中的 \s)分割结果。 然后带有 ~ 的值是您的短文件名。如果您的文件名开头很短,那么您将找不到包含 ~ 的字符串。

【讨论】:

  • 一种相当低效的方法。我希望调用批处理脚本的效率会大大提高。
【解决方案3】:

这是一个在注册表中读取“appdata\local”文件夹位置并将其转换为短路径的示例:

cls
@echo off
cd /d "%~dp0"
chcp 65001 >nul

for /f "skip=1" %%a in ('"wmic useraccount where name='%USERNAME%' get sid"') do (
    for %%b in (%%a) do set current_SID=%%b
)
set current_username=%USERNAME%
set current_userprofile=%USERPROFILE%

set key_to_read=HKEY_USERS\%current_SID%\Software\Microsoft\Windows\CurrentVersion\Explorer\User Shell Folders
set value_to_read=Local AppData
rem If value_to_read contains ? space(s) set tokens to 2+?
for /f "usebackq eol= tokens=3,* delims= " %%a in (`reg query "%key_to_read%" /v "%value_to_read%" 2^>nul ^| find "%value_to_read%"`) do (
    set value_type=%%a
    set data_read=%%b
)
set data_read=%data_read:USERPROFILE=current_userprofile%
call set "data_read=%data_read%"
set current_local_appdata=%data_read%

set current_local_appdata_temp=%current_local_appdata%\Temp
echo %current_local_appdata_temp%

for %%a in ("%current_local_appdata_temp%") do set "current_local_appdata_temp_short=%%~sa"
echo %current_local_appdata_temp_short%

pause
exit

【讨论】:

  • 很遗憾,您的回答没有回答问题。因此,将来可能会被删除。但是,它可能对其他人有用。我建议您提出一个新问题(即使您知道答案),然后自己直接回答该问题。
猜你喜欢
  • 2012-04-30
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2010-10-27
相关资源
最近更新 更多