How to Get the Short (8.3) Filename in Batch Script
Long filenames with spaces are standard today, but some older applications or legacy command-line tools can't handle them. For compatibility, you may need to convert a modern path like "C:\Program Files\" into its short (8.3 or MS-DOS) equivalent, which is often "C:\PROGRA~1". This 8.3 format consists of a name up to 8 characters long and an extension up to 3 characters long.
This guide will teach you how to use built-in batch script parameter expansions to easily retrieve the short 8.3 name for any file or folder, a crucial technique for ensuring backward compatibility in your automation scripts.
The Core Method: FOR Command Parameter Expansion
The primary way to get a short filename in a batch script is by using a FOR loop. While typically used for iteration, it gives us access to powerful modifiers that can transform a filename string.
The key is the ~s modifier:
FOR %%F IN ("Long Filename.txt") DO ...: This sets up a loop where%%Fholds the filename.%%~sF: Inside the loop, this special syntax expands%%Fnot to its original form, but to its short 8.3 path.
Basic Example: Getting the Short Name of a File
Let's find the short name for a file with a long name containing spaces.
@ECHO OFF
ECHO Finding the short name for "My Important Document.txt"...
ECHO.
FOR %%I IN ("My Important Document.txt") DO (
ECHO The long name is: "%%I"
ECHO The short name is: %%~sI
)
Output is the following (Assuming the file exists in the current directory, the system automatically provides the generated 8.3 name):
Finding the short name for "My Important Document.txt"...
The long name is: "My Important Document.txt"
The short name is: MYIMPO~1.TXT
Getting the Short Path for a Directory
This same technique works perfectly for directory paths, which is one of its most common use cases.
For example, here we find the short name for the "Program Files" directory.
@ECHO OFF
FOR %%D IN ("C:\Program Files") DO (
ECHO The long path is: "%%D"
ECHO The short path is: %%~sD
)
Output
The long path is: "C:\Program Files"
The short path is: C:\PROGRA~1
Storing the Short Name in a Variable
To use the short path later in your script, you need to capture it in a variable.
@ECHO OFF
SET "LONG_PATH=C:\Program Files (x86)"
SET "SHORT_PATH="
REM Use the FOR loop to populate the variable.
FOR %%P IN ("%LONG_PATH%") DO SET "SHORT_PATH=%%~sP"
IF DEFINED SHORT_PATH (
ECHO The short path for "%LONG_PATH%" is: %SHORT_PATH%
) ELSE (
ECHO Could not determine the short path.
)
Output:
The short path for "C:\Program Files (x86)" is: C:\PROGRA~2
Common Pitfalls and How to Solve Them
Problem: 8.3 Name Generation is Disabled on the System
On modern Windows systems, especially for non-system drives, the creation of 8.3 filenames might be disabled by default to improve performance. If this is the case, the %%~sF modifier will not return an error; it will simply return the original long filename.
Solution: Check with fsutil
You can check the status of 8.3 name generation with the fsutil command (requires administrator privileges).
Command to check the status:
fsutil 8dot3name query
Output if enabled:
The registry state is 0 (8dot3 name creation is enabled on all volumes).
Output if disabled:
The registry state is 2 (8dot3 name creation is disabled on all volumes).
If it's disabled, you can enable it with fsutil 8dot3name set 0, but be aware this may have performance implications and requires careful consideration.
Problem: Handling Files Passed as Arguments
If your script receives a filename as a command-line argument (%1), using a FOR loop is unnecessary. Batch provides a direct way to apply the ~s modifier to arguments.
Solution: Use %~s1
The syntax ~s can be applied directly between the % and the argument number.
@ECHO OFF
IF "%~1"=="" (
ECHO Please provide a filename as an argument.
GOTO :EOF
)
ECHO The long path you provided is: %1
ECHO The short path is: %~s1
Usage and Output
C:\> GetShortName.bat "C:\My Project Files\data.csv"
The long path you provided is: "C:\My Project Files\data.csv"
The short path is: C:\MYPROJ~1\data.csv
Practical Example: Passing a Short Path to a Legacy Application
This script demonstrates a real-world scenario where a legacy tool (legacy_tool.exe) cannot process input files if their path contains spaces.
@ECHO OFF
SETLOCAL
SET "DATA_FILE=C:\Users\Test User\My Documents\Latest Sales Data.csv"
ECHO --- Legacy Data Processor ---
IF NOT EXIST "%DATA_FILE%" (
ECHO [ERROR] Source file not found: "%DATA_FILE%"
GOTO :End
)
ECHO Converting path to 8.3 format for legacy tool...
FOR %%F IN ("%DATA_FILE%") DO (
SET "SHORT_DATA_FILE=%%~sF"
)
ECHO Long path: "%DATA_FILE%"
ECHO Short path: "%SHORT_DATA_FILE%"
ECHO.
ECHO Calling legacy tool with the short path...
legacy_tool.exe --input "%SHORT_DATA_FILE%"
:End
ENDLOCAL
By converting the path first, we ensure the legacy_tool.exe receives a path it can correctly parse, like C:\Users\TESTUS~1\MYDOCU~1\LATEST~1.CSV.
Conclusion
Getting the 8.3 short filename is a vital compatibility tool for interacting with older programs. The built-in parameter expansion modifiers in Windows Batch make this task simple and efficient.
- For file paths stored in variables, use a
FORloop with the%%~sFmodifier. - For file paths passed as command-line arguments, use the direct
%~s1syntax. - Always be aware that 8.3 name generation might be disabled on the target system. Use
fsutil 8dot3name queryto verify if you encounter issues.
By mastering this technique, you can greatly improve the robustness and backward compatibility of your batch scripts.