How to Extract a Substring by Position in Batch Script
Extracting a portion of a string (a "substring") is a critical operation for parsing data. You might need to get the year from a date stamp, extract a user's initials from their full name, or read a fixed-length field from a line in a log file. While batch scripting has no dedicated SUBSTRING() function, it has a powerful and concise built-in syntax for this task using variable expansion.
This guide will teach you how to use the special ~ modifier to extract substrings from the beginning, middle, or end of a string. You will learn the zero-based indexing system and the correct syntax for specifying a starting position and length, enabling you to precisely parse any string your script encounters.
The Core Syntax: %VariableName:~start,length%
The entire mechanism for substrings is built into the variable expansion syntax.
%VariableName:~start,length%
VariableName: The name of the variable containing your source string.~: A special character that signals the start of a modifier operation.start: The starting position of the substring. This is a zero-based index.length: The number of characters you want to extract. This is optional; if omitted, it will take all characters from the start position to the end of the string.
Basic Examples: Getting Parts of a String
Let's use a consistent source string for all our examples to make the logic clear.
SET "MyString=Abcdef12345"
Extracting from the Beginning
To get the first N characters, you start at index 0.
@ECHO OFF
SET "MyString=Abcdef12345"
REM Get the first 3 characters
ECHO First 3: %MyString:~0,3%
REM Get all characters starting from the 4th character (index 3)
ECHO From index 3 to the end: %MyString:~3%
Output:
First 3: Abc
From index 3 to the end: def12345
Extracting from the End
To get the last N characters, you use a negative start index. This is a powerful shortcut.
@ECHO OFF
SET "MyString=Abcdef12345"
REM Get the last 5 characters
ECHO Last 5: %MyString:~-5%
REM Get all characters EXCEPT the first 6
ECHO All except first 6: %MyString:~6%
Output:
Last 5: 12345
All except first 6: 12345
A negative start index counts from the end of the string. There is no concept of a negative length.
Extracting from the Middle
To get a substring from the middle, you specify both a start and a length.
@ECHO OFF
SET "MyString=Abcdef12345"
REM Start at the 4th character (index 3) and take 4 characters
ECHO Middle 4: %MyString:~3,4%
Output:
Middle 4: def1
Storing the Result in a New Variable
In most scripts, you'll want to store the extracted substring in a new variable for later use. This is done with a standard SET command.
@ECHO OFF
SET "MyString=Abcdef12345"
SET "FirstPart=%MyString:~0,6%"
SET "SecondPart=%MyString:~6,5%"
ECHO The first part is "%FirstPart%"
ECHO The second part is "%SecondPart%"
Output:
The first part is "Abcdef"
The second part is "12345"
Common Pitfalls and How to Solve Them
The "Zero-Based" Indexing System
This is the most common point of confusion for beginners. Unlike some languages where the first character is at position 1, in batch scripting, the first character is at position 0.
For our string Abcdef12345:
- Index
0=A - Index
1=b - Index
2=c - ...and so on.
Solution: Always remember this rule. To get the first character, you use ~0,1, not ~1,1.
Handling Negative Lengths (and Why They Don't Work)
The length parameter cannot be negative. A command like %MyString:~3,-2% (meaning "start at index 3 and go until 2 from the end") is not valid syntax and will not work.
Solution: If you need to perform a complex extraction like this, you must calculate the correct positive length manually or perform multiple substring operations.
Using Substrings Inside a Loop (Delayed Expansion)
If you are modifying a variable inside a FOR loop and also trying to take a substring of it, you must use delayed expansion. Standard percent variables (%Var%) are expanded only once before the loop begins.
@ECHO OFF
SETLOCAL ENABLEDELAYEDEXPANSION
SET "MyVar=ABC"
FOR /L %%i IN (1,1,3) DO (
REM Add a number to the end of the variable
SET "MyVar=!MyVar!%%i"
REM Get the last character using delayed expansion
ECHO Current string: !MyVar!
ECHO Last char is: !MyVar:~-1!
)
Output:
Current string: ABC1
Last char is: 1
Current string: ABC12
Last char is: 2
Current string: ABC123
Last char is: 3
Practical Example: Parsing a YYYY-MM-DD Date String
This is a classic use case. The script takes a date formatted as YYYY-MM-DD and breaks it into its component parts.
@ECHO OFF
SET "DateStamp=2023-10-27"
ECHO Original Date: %DateStamp%
SET "Year=%DateStamp:~0,4%"
SET "Month=%DateStamp:~5,2%"
SET "Day=%DateStamp:~8,2%"
ECHO.
ECHO --- Parsed Components ---
ECHO Year: %Year%
ECHO Month: %Month%
ECHO Day: %Day%
Output:
Original Date: 2023-10-27
--- Parsed Components ---
Year: 2023
Month: 10
Day: 27
Conclusion
The substring syntax in batch scripting is a powerful, concise, and efficient tool for string manipulation, eliminating the need for complex loops for simple parsing.
Key syntax rules to remember:
- The general format is
%VAR:~start,length%. - The
startindex is zero-based. - To get the last N characters, use a negative start index:
%VAR:~-N%. - The
lengthparameter is optional and must be positive. - For use inside a changing
FORloop, you must use delayed expansion:!VAR:~start,length!.