How to write a volume label into a variable the right way? - batch-file

I wanna save the volume label into the variable %volume%.
The normal Syntax would be:
C:\Users\volk>for /f "tokens=1-5*" %%1 in ('vol C:') do set volume=%%6
This way I get an syntax error that says %%1 was unexpected at this time.
So I tried a different solution:
C:\Users\volk>for /f "tokens=1-5*" %1 in ('vol C:') do set volume=%6
C:\Users\volk>set volume=System
C:\Users\volk>set volume=
But this way %volume% is filled with System and in the next step overwritten
with 'nothing' (variable is empty and not existing again).
I´m working in a Windows 8 PE(dont´t know if it´s important for a solution).

for /f "tokens=5,*" %a in ('vol C:') do set volume=%b
works for me. If you get a second setcommand, just filter out the needed lines:
for /f "tokens=5,*" %a in ('vol C:^|find ":"') do set volume=%b
Note: %x is for use at the command prompt. Inside a batch file you need to use %%x

Try to distinguish SET outputs by adding suffix to a variable name, like:
for /f "tokens=1-5*" %1 in ('vol C:') do set volume%2=%6
As long as you can consistently identify this suffix in a 'vol C:' output, you know the variable name storing your Volume name.
In my case %2="in", so my desired variable names "volumein".

Related

Exclude text from last delimiter found

I have a bat file that extracts the target of the given shortcut in the parameter
#echo off
set "paf=%*"
for /f "delims=" %%a in ('wmic path win32_shortcutfile where "name='%paf:\=\\%'" get target /value') do (
for /f "tokens=2 delims==" %%b in ("%%~a") do CALL SET shortcutPath=%%a
)
The return is like: C:\Users\MyUser\Desktop\SomeFolder\target.exe
All I want is to get the folder path without the executable name. This is a bat that I'll use constantly with different given shortcuts from many locations so it has to be relative.
On how to achieve this, I thought on exclude all characters from the last delimiter found, the delimiter should be \ and it will exclude anything on the right side of the last one found. The thing is I have no idea how to do that, or even if this is possible
Can someone bring some help on this?
Thank you
The simplest way is to use the already existing output Target name, instead of assigning the name shortcutPath to it. As long as your passed argument is a valid and working shortcut file, your resulting variable will be accessible as %Target%.
Set "Target=" & For /F "Delims=" %%G In ('%SystemRoot%\System32\wbem\WMIC.exe
Path Win32_ShortcutFile Where "Name='%Lnk:\=\\%'" Get Target /Value 2^>NUL'
) Do For /F "Delims=" %%H In ("%%G") Do Set "%%H"
Then given your Target variable contains the full path and file name, you can use variable expansion modifiers to return its drive and path only:
If Defined Target For %%G In ("%Target%") Do Echo %%~dpG
If you want it without the trailing backwards slash, you could return that by including another for loop, and changing the modifier:
For %%G In ("%Target%") Do For %%H In ("%%~dpG.") Do Echo %%~fH
Instead of CALL SET shortcutPath=%%a, use
SET "shortcutPath=%%~dpb"
The result should be C:\Users\MyUser\Desktop\SomeFolder\ in your given example.
For explanation, read and follow for /?:
%~dpI - expands %I to a drive letter and path only
Read more about using quotes in https://ss64.com/nt/set.html.

Batch File: "Environment Variable Not Defined" on a path

I have the following in a batch file
for /f "delims=" %%a in ("C:\Program Files (x86)\Wowza\creds.txt") do set %%a
net use J: https://csv/dav %p% /user:%u% /persistent:yes
I get an error:
Environment variable C:\Program Files (x86)\Wowza\creds.txt not defined
What do I need to resolve this?
Secondly, it works for all colleagues apart from one. Same laptop make, model and build. I used my details and it failed on his but worked on mine.
What fails is that it asks for the credentials to map the drive instead of taking them from the file
creds.txt
u:JoeBloggs
p:Password1234
Any idea?
Thanks
the reason for your errormessage is, your for /f loop doesn't evaluate the contents of the file. It takes a quoted string as string not as filename. Usebackq changes that behaviour.
You have another failure in your script: With your code, set %%a translates to set u:JoeBloggs, which is invalid syntax. Correct syntax requrires set u=Joebloggs. Therefore you have to split the line in a part before the colon and a part after the colon and build your set command accordingly (just set %%a would work, when the contents of the file would look like u=JoeBloggs)
Change your for loop to:
for /f "usebackq tokens=1,* delims=:" %%a in ("C:\Program Files (x86)\Wowza\creds.txt") do set "%%a=%%b"
I was going to post a similar answer to #stephan but he beat me to it. If however you have the option to change your creds.txt file to the below:
u=JoeBloggs
p=Password1234
You can shorten the for loop a bit to this:
for /f "usebackq delims=" %%a in ("C:\Program Files (x86)\Wowza\creds.txt") do set "%%~a"
which effectively just does this:
set "u=JoeBloggs"
set "p=Password1234"

Using "for /F" command to find specific text in xml file and use as variable in a batch file

I am trying to find the following version number in a app.config file.
The file is XML format.
Line 8 in the file (Adding line in again as the greater/less than symbols were stripped from the post initially)
add key="ReleaseVersion" value="5.2.0.2"
I been using various FOR /F commands, have been close a couple of times.
However I have not been able to extract the 5.2.0.2 value and use as a variable
so far in my script.
Additionally while I am looking for this value 5.2.0.2, going forward the version number will change so I am not looking for a exact match e.g. "5.2.0.2", I am looking to capture what is in the inverted commas e.g. value="", and then using this as a variable in my script.
Example of what I have tried so far...
FOR /f "tokens=3 delims=5." %%a IN ('TYPE appsettings.config ^| FIND "ReleaseVersion"') DO SET do set word3=%%a
FOR /F delims^=^"^ tokens^=2 %%G IN ('FINDSTR /L "ReleaseVersion" "appsettings.config"')
FOR /f "tokens=3 usebackq delims== " %%G in (`appsettings.config`) do #echo %~G
Have tried a number of techniques but as yet, nothing has been successful.
Can post more information as required however that essentially covers the issue.
Supposing the add key="ReleaseVersion" value="5.2.0.2" portion is in a single line and the related value parameter appears after the ReleaseVersion substring, the following could work for you:
#echo off
setlocal EnableExtensions DisableDelayedExpansion
rem define constants:
set "SEARCH=ReleaseVersion"
set "KEYWORD=value"
rem get line of interest and assign it to `LINE`:
for /F "delims=" %%L in ('findstr /L "%SEARCH%" "app.config"') do (
set "LINE=%%L"
)
setlocal EnableDelayedExpansion
rem cut everything off up to the search string:
set "LINE=!LINE:*%SEARCH%=!"
rem cut everything off up to the keyword:
set "LINE=!LINE:*%KEYWORD%=!"
rem extract the version number:
for /F tokens^=1^ delims^=^"^=^/^<^>^ %%N in ("!LINE!") do (
set "VNUM=%%N"
)
rem transfer the version number over the `setlocal`/`endlocal` barrier:
endlocal & endlocal & set "VNUM=%VNUM%"
echo ReleaseVersion: %VNUM%
exit /B
The string portion of interest does not need to look exactly like shown above, but may contain more or less spaces (for example add key = "ReleaseVersion" value = "5.2.0.2"), or include the " or not (like add key=ReleaseVersion value=5.2.0.2). The only condition is that the attribute key needs to appear before the attribute value.
If the search line is precisely this one:
add key="ReleaseVersion" value="5.2.0.2"
... then this code should work:
#echo off
setlocal
for /F "tokens=3" %%a in ('findstr "ReleaseVersion" "appsettings.config"') do set %%a
set "value=%value:~1,-1%"
echo %value%
If the layout of the search line change (more blank spaces or other characters, less quotes, etc) then previous code should need an adjustment.
#ECHO OFF
SETLOCAL
SET "sourcedir=U:\sourcedir"
SET "filename1=%sourcedir%\q34445384.txt"
FOR /f "tokens=3delims==" %%a IN (
'findstr /L /c:"add key=\"ReleaseVersion\" value=" "%filename1%"') DO SET "release=%%~a"
ECHO release=%release%
GOTO :EOF
You would need to change the setting of sourcedir to suit your circumstances.
I used a file named q34445384.txt containing your data for my testing.
Simply find the target string using findstr and set the environment variable to the third token using delimiters of =, removing the quotes from the value with ~.
This assumes uniqueness of the target text and that the structure of the line is exactly as posted.
Assuming app.config is valid, well-formed XML, the best way to scrape the release version is to query it via XPath. You can invoke PowerShell for this.
#echo off
setlocal
set "psCommand=powershell "^
select-xml \"//add[#key^='ReleaseVersion']\" app.config ^| %%{ $_.node.value };^
""
for /f %%I in ('%psCommand%') do set "version=%%~I"
echo %version%
This will parse app.config for a node named "add" which has an attribute named "key" whose value is "ReleaseVersion", then will return that node's "value" attribute's value. for /f captures it to a batch variable.

Windows shell: get parameter value from file

I have a file C:\parameters.txt that contains different parameters, for example:
env_user=username123
env_pw=password123
env_url=example.com
Now I created a .cmd file that needs to get these values and put them in a variable, for example:
SET var_user=<Here I need 'username123'>
SET var_pw=<Here I need 'password123'>
SET var_url=<Here I need 'example.com'>
How do I write this in my cmd script to get the correct values for my variables?
You need to set a delimiter for = character so that words before/after = will be separated. Besides that, you need an array to set each of the parameters. You can do it like this:
#echo off
setlocal enabledelayedexpansion
set increment=0
for /f "tokens=1* delims==" %%a in (C:\parameters.txt) do (
set parameters_array[!increment!]=%%b
set /a increment+=1
)
echo %parameters_array[0]%
echo %parameters_array[1]%
echo %parameters_array[2]%
pause >nul
Keep in mind, array always starts from 0. You could change to set increment=1 if you prefer the array starts from 1.
Just a slight alternative to dark fang's solution, since your parameters.txt file's contents are already in the format of variable=value, you could
#echo off
setlocal
for /f "usebackq delims=" %%I in ("c:\parameters.txt") do set "%%I"
rem // display env_* variables
set env_
pause
The usebackq option allows you to quote the file name, which might be needed if you ever move c:\parameters.txt to a location containing spaces, ampersands, or other tricksy characters. It's a good habit to follow when reading the contents of text files with for /f.
Also, it's better not to use delayed expansion if you don't need it, as delayed expansion can sometimes corrupt values containing exclamation marks -- a situation that is reasonably possible when dealing with passwords.
I've found the solution thanks to different inputs.
#echo off
For /F "tokens=1* delims==" %%A IN (C:\parameters.txt) DO (
IF "%%A"=="env_user" set var_user=%%B
IF "%%A"=="env_pw" set var_pw=%%B
IF "%%A"=="env_url" set var_url=%%B
)
This will set the correct variables (not local) once the specific code name (before the = in parameters.txt) has been found.

Delayed expansion doesn't work inside delayed expansion

I've got a script that does everything I expect it to do, apart from one line.
I've done similar before, but I can't get this one to work.
The code I've got is here
#echo off
SETLOCAL ENABLEDELAYEDEXPANSION
::Set Path to be folder of Sage Files
SET PATH=C:\Welcome\Progs\SitesDataSetups\GeorgeYarmouth
::set date variables
for /f "tokens=1" %%i in ('date /t') do set thedate=%%i
set mm=%thedate:~3,2%
set dd=%thedate:~0,2%
set yyyy=%thedate:~6,4%
::Set T_DAY variable to date in ddmmyy format
set T_DAY=%dd%%mm%%yyyy:~2%
c:
cd\
cd %path%
for /f "usebackq tokens=* delims= " %%P in (`dir sage*.csv /od /b`) do (
set SAGE=%%P
set SAGE2=!SAGE:~0,8!_EDITED
set EODNUM=!SAGE:~4,4!
for /f "tokens=* delims= " %%A in (%%P) do (
echo %EODNUM%
set S=%%A
***This line is the problem***
set S=!S:%T_DAY%=%EODNUM%!
echo.!S! >> %PATH%\TEST\!SAGE2!.csv
)
)
endlocal
I was expecting that is would take each line of the csv file and replace it with itself, except with a string replace of the current date with the variable EODNUM (which it does... only the variable is expanded before it is set, so is nothing)... The delayed expansion should solve this, but I can use this line of code
set S=!S:%T_DAY%=!EODNUM!!
because I think its too many !'s for CMD.
Am I missing something, or is there a better way to code this?? (I'm not a programmer of any kind, and most of the code I write comes from trial and error, and 'borrowing' from other scripts, so this may be a very messy way to do this).
Transfer the the value of !EODNUM! to a FOR variable, and then use your FOR variable as the replace string.
echo !EODNUM!
set "S=%%A"
for /f "delims=" %%E in ("!EODNUM!") do set "S=!S:%T_DAY%=%%E!"
echo.!S!>> %PATH%\TEST\!SAGE2!.csv
By way of explanation...
CMD reads (and does env var substitution), parses, and executes one top-level command at a time.
In your example, it reads the "for /f..." command all at once parsing and performing %var% substitution.
Once this is complete, it then executes the for loop, performing delayed !var! substitution.
Unfortunately, !var! substitution is not a do-substitution-until-none-left. This makes it hard (as in the answerer's solution) to perform the substitution into the !var:src=dst! value.
You will need a way that during execution you can get guaranteed substitution. This requires a for-statement, or something that involves reading and %var% substituting again. One way of doing this is to use the CALL :LABEL form where you can call to a specific label in your .cmd file and have this section do what you want:
...
call :GenS
...
and then:
:GenS
set S=!S:%T_DAY%=%EODNUM%!
goto :eof
BTW: I'm perplexed that you didn't notice the ECHO %EODNUM% not working in the loop as during the reading of the for loop all %var% substitutions are made.

Resources