Batch SET: Separate Variables On Each Line
Hey guys! Ever found yourself staring at a SET statement in your batch scripts, wishing you could just neatly tuck each variable onto its own line? You know, that moment when you’ve got a whole bunch of data crammed into one string, like set "datastr=%num_cde%, %id_achat%, %modele%, %sysfam%, %serial%, %ldt%", and you’re thinking, “This is going to be a nightmare to parse later, especially when it pops up in an email body or needs further processing.” Well, you’re not alone! It’s a common little hiccup that can make your scripts harder to read and maintain. The good news is, there are some super slick ways to handle this, making your batch scripting life a whole lot easier. We’re talking about transforming that single, dense line into something much more manageable, breaking down those variables so they’re accessible and understandable. This isn’t just about aesthetics, though it certainly cleans things up; it’s about efficiency and preventing headaches down the line when you need to access or manipulate individual pieces of data. Let's dive into how we can untangle those variable strings and get them organized, making your batch files more robust and readable than ever before.
The Challenge of Single-Line SET Statements
So, you’ve got this data string, right? Like the example set "datastr=%num_cde%, %id_achat%, %modele%, %sysfam%, %serial%, %ldt%". It’s perfectly functional for just storing a bunch of related info together. But here’s the rub: when you need to use these individual pieces later, it gets messy. Imagine you want to send an email, and you need to format each piece of data separately, or perhaps you need to log each value with a specific label. Echoing that datastr directly into an email body might look something like SET "EmailBody=... %num_cde%, %id_achat%, %modele%, %sysfam%, %serial%, %ldt% ...". It’s all mushed together! Parsing this string later in another batch script or even within the same script can involve a lot of substring manipulation, finding delimiters (like the comma and space in this case), and then extracting each bit. This is not only tedious but also prone to errors. What if one of the values itself contains a comma? Your parsing logic might go haywire. What if the order of variables changes? Your script breaks. This is where the need to separate variables on each line becomes super apparent. It’s about making your data structured and easily addressable. Instead of treating it as one long string, you want to treat each variable as a distinct entity, which makes processing, debugging, and reusing your code significantly simpler. Think of it like organizing your tools in a toolbox versus throwing them all into one big bin – much easier to find what you need when it’s neatly arranged!
Method 1: Using FOR /F to Parse and Reassign
Alright, let’s get down to business with the first and arguably the most common way to tackle this: using the mighty FOR /F command. This command is a powerhouse for parsing text, and it’s perfect for grabbing those individual variables from your string and putting them onto their own lines. The basic idea is to tell FOR /F to treat your string as a file or as command output, and then to split it up based on delimiters. Here’s how you can do it:
@echo off
set "num_cde=123"
set "id_achat=ABC"
set "modele=XYZ"
set "sysfam=Server"
set "serial=SN7890"
set "ldt=2023-10-27"
set "datastr=%num_cde%, %id_achat%, %modele%, %sysfam%, %serial%, %ldt%"
echo Original datastr: %datastr%
:: Use FOR /F to parse the string
:: "tokens=*" means grab the whole line if no delimiter is specified, but we will specify.
:: "delims=," tells it to split by comma
:: "usebackq" is often used with file paths, but here it helps handle quotes in the string if any.
:: "(" ... ")" encloses the command whose output will be parsed.
for /f "tokens=1-6 delims=," %%a in ("%datastr%") do (
set "var1=%%a"
set "var2=%%b"
set "var3=%%c"
set "var4=%%d"
set "var5=%%e"
set "var6=%%f"
)
:: Now, display them separated
echo -- Separated Variables --
echo Variable 1 (num_cde): %var1%
echo Variable 2 (id_achat): %var2%
echo Variable 3 (modele): %var3%
echo Variable 4 (sysfam): %var4%
echo Variable 5 (serial): %var5%
echo Variable 6 (ldt): %var6%
How it works:
for /f "tokens=1-6 delims=," %%a in ("%datastr%") do (...): This is the core of the operation.delims=,: This tellsFOR /Fto use the comma (,) as the delimiter to split the string.tokens=1-6: This is crucial. It specifies that we want to capture the first six tokens (pieces of the string separated by the delimiter).%%awill get the first token,%%bthe second, and so on, up to%%ffor the sixth.in ("%datastr%"): This indicates that the input string we wantFOR /Fto process is contained within thedatastrvariable. The double quotes around%datastr%are good practice to handle potential spaces or special characters within the string itself.
set "varX=%%y": Inside thedoblock, we reassign each captured token (%%a,%%b, etc.) to a new variable. Important: Notice theset "varX=%%y"syntax. This is the safest way to set variables, especially if the values might contain spaces or special characters. It also trims leading spaces from the token, which is super handy because our original string had spaces after the commas (e.g.,,). If you didn't want that leading space trimmed, you'd need a slightly more complex approach, but usually, trimming is desired.
This method gives you individual variables (%var1%, %var2%, etc.) that you can then use, echo, or format as needed. It's clean, effective, and a fundamental technique for any serious batch scripter. You can adjust the tokens= part based on how many variables you have. If you had more, you'd list them like tokens=1-8 and use %%g, %%h, etc. Pretty neat, right?
Method 2: Using CALL with Delayed Expansion (for Echoing to Separate Lines)
Sometimes, you don't necessarily need to assign each part to a new variable. Maybe you just want to display each part on its own line, perhaps for logging or an email body, and you want to do it directly without creating dozens of temporary variables. This is where delayed expansion can be your best friend, especially when combined with CALL in a loop. Let's say you want to construct that email body, but with each piece of data on a new line.
Consider this scenario: you have the same datastr as before, and you want to build an EmailBody where each element from datastr is preceded by a label and placed on its own line.
@echo off
setlocal enabledelayedexpansion
set "num_cde=123"
set "id_achat=ABC"
set "modele=XYZ"
set "sysfam=Server"
set "serial=SN7890"
set "ldt=2023-10-27"
set "datastr=%num_cde%, %id_achat%, %modele%, %sysfam%, %serial%, %ldt%"
echo Original datastr: %datastr%
set "EmailBody=
"
:: Define an array-like structure using CALL and labels
call :add_data "Number Code" %num_cde%
call :add_data "Purchase ID" %id_achat%
call :add_data "Model" %modele%
call :add_data "System Family" %sysfam%
call :add_data "Serial Number" %serial%
call :add_data "Last Date" %ldt%
echo -- Email Body --
echo %EmailBody%
goto :eof
:add_data
:: This subroutine appends a labeled line to EmailBody
:: %1 is the label, %2 is the value
set "EmailBody=!EmailBody!%1: !%2!
exit /b
Explanation:
setlocal enabledelayedexpansion: This is key. It allows variables like!EmailBody!to be evaluated at the time they are used, rather than when the line is parsed. This is essential for building strings within loops or conditional blocks.call :add_data "Label" %variable%: We useCALLto invoke a subroutine (labeled:add_data).CALLis used here because we want to pass the values of the variables (%num_cde%,%id_achat%, etc.) as arguments to the subroutine. If we just used `:add_data