Reading a variable in a for loop in a bat file - windows

I am trying to print lines from a file in the below for loop:
SET my-file="C:\tmp\xxx.txt"
#echo off
for /f "tokens=*" %%a in (%my-file%) do (
echo line=%%a
)
Where:
C:\tmp\xxx.txt contains:
a
b
c
d
But the %my-file% is not expanded. How do I use a variable in the for loop?

By putting quotes around the path, the variable is treated as a string, not a path. So %my-file% will contains the name of the file, not it's content.
you can use the same code without the quotes (if the path allows it), or use type to read the file content :
SET my-file="C:\tmp\xxx.txt"
#echo off
for /f "tokens=*" %%a in ('type %my-file%') do (
echo line=%%a
)

Your code works. If you have problems remove the echo off - which shows you that it is working.
This is your program in it's essense.
for /f "tokens=*" %%a in ("C:\tmp\xxx.txt") do echo line=%%a
And it should print, because someone put it in quotes, C:\tmp\xxx.txt as quotes mean the string is the content. No quote single or double is a filename. Single quote is a command.
If you need quotes you use UseBackQ option to move the single/double/no quote meanings around.
see For /?
Most of your batch is voodoo.
Extra unneeded brackets and sticking literals into variables.

Related

Double quotes in delims=?

I'm very new to batch scripting, but in my last question I was trying to extract a link from a line of text, specifically:
83: href="https://beepbeep.maxresdefault.rar"><img
What I want out of it is this:
https://beepbeep.maxresdefault.rar
Someone suggested using for /f to separate the string, and I'd like to separate it every " mark, taking only the second token, as what I want is trapped between the two "".
Here is what I've got:
for /f "delims=^" tokens=^2" %%G in (output2.txt) do #echo %%G %%H >> output3.txt
The batch crashes at this point, I'm guessing it's the wrong syntax, but I'm not sure where the issue is, maybe in the " part?
See how we delimit on double quotes, without surrounding quotes. We have already assigned the variable between the quotes to %%a but if we did not, then to remove the double quotes from the string we expand the variable %%a to %%~a (see for /? on variable expansion):
#for /f delims^=^"^ tokens^=2 %%a in (output2.txt) do #echo %%~a
Neat problem.
I'd do it this way:
SETLOCAL ENABLEDELAYEDEXPANSION
for /F "tokens=2 delims=^>=" %%i in (output2.txt) do (
set x=%%i
set x=!x:"=!
echo !x! >> output3.txt
)
Notes:
Instead of tokenising on the quote, I've tokenised on = (before) and > (after). Because, as you already know, quotes are hard
I always do the delims last. Otherwise it might think the space between delims and tokens is a delimeter.
Then it uses the SET syntax that allows you to substitute one character for another to replace all occurances of the double quote with nothing.
The SETLOCAL ENABLEDELAYEDEXPANSION is necessary because otherwise, each evaluation of the %x% in the loop uses the original value of %x% which is probably wrong. I always have this as the second line in my batch file.
Judging by how much you've already got, I'm guessing you've seen it, but if you haven't, I've found ss64.com to be the best resource.
https://ss64.com/nt/syntax-dequote.html

Batch file - How to find quotes in a string?

When given an environment variable that may or may not be quoted I need to remove the quotes.
For example, I may be given:
JAVA_HOME=C:\Program Files\Java\jdk1.8.0_144
JAVA_HOME="C:\Program Files\Java\jdk1.8.0_144"
I am trying to use findstr and it seems to work well from cmd.exe but not from my batch file. This is what I have in test1.bat:
#echo off
echo.%JAVA_HOME% | findstr \^" 1>nul
if ERRORLEVEL 0 (
echo Found Quotes
)
if ERRORLEVEL 1 (
echo No Quotes found
)
The problem I have is that the ERRORLEVEL always seems to be 0 and I always get the message "Found Quotes" when I run test1.bat.
I have this code to remove quotes for /f "delims=" %%G IN (%JAVA_HOME%) DO SET JAVA_HOME=%%G which works find, but only when there are quotes, hence needing to get the above findstr conditions working correctly.
Batch files already have the ability to remove quotes on for-loop variables like %%G in your example, so you do not need any of that findstr logic. The reason why your for doesn't work is because you're not quoting the %JAVA_HOME%. You always have to quote arguments that have spaces.
From help for, the syntax is:
FOR /F ["options"] %variable IN ("string") DO command
[command-parameters]
And on automatic variables like %%G, the tilde operator removes quotes if they are present.
From help for:
In addition, substitution of FOR variable references has been
enhanced. You can now use the following optional syntax:
%~I - expands %I removing any surrounding quotes (")
So with these 2 pieces of information, change your for loop to this to remove quotes from %JAVA_HOME%.
for /f "delims=" %%G IN ("%JAVA_HOME%") DO SET "JAVA_HOME=%%~G"
You typically have to test for other values for ERRORLEVEL before testing for 0, IIRC. This works perfectly for me:
#echo off
echo.%JAVA_HOME% | findstr \^" 1>nul
if ERRORLEVEL 1 (
echo No quotes found
goto :eof
)
if ERRORLEVEL 0 (
echo Found quotes
)
NOTE: Removing the goto :eof means you get both lines output by echo if there is no match.
#ECHO OFF
SETLOCAL
SET JAVA_HOME=C:\Program Files\Java\jdk1.8.0_144
SET "java_home=%java_home:"=%"
SET j
ECHO -------------------------------------------
SET JAVA_HOME="C:\Program Files\Java\jdk1.8.0_144"
SET "java_home=%java_home:"=%"
SET j
GOTO :EOF
Either way, java_home ends up "nude".

%%I in windows batch doesn't manage name with spaces

In windows 10, I need to make a batch with a loop on the subfolder names in a folder, I did the following, but the problem is the %%I doesn't manage the folder name with spaces, it takes only the first part:
#echo off
FOR /F %%I IN ('dir /b C:\Users\Thomas\Music') DO (
ECHO %%I)
If the folder "Music" contains the folder "My music", then echo %%I will print only "My".
FOR /F "delims=" %%I IN ('dir /b /ad C:\Users\Thomas\Music') DO (
... and use "%%I" where you want to use the name-containing-spaces (ie. quote the constructed string) - a principle that applies wherever batch uses strings containing separators like Space
The /ad selects directorynames instead of filenames.
Adding a further switch, /s will scan the entire subdirectory-tree.
Assignment of string values to variables is best done with
set "var=%variablefrom%"
or in the case of a metavariable (eg the loop-control variable %%I in your code) you need
set "var=%%I"
BUT you should investigate the topic of delayed expansion (many items here) if you want to use the value of the variable assigned (var) within the loop.
My best-practice concept shown in a commented .bat script:
#ECHO OFF
SETLOCAL EnableExtensions DisableDelayedExpansion
FOR /F "delims=" %%I IN ('dir /b /AD "%UserProfile%\Music" 2^>NUL') DO (
rem process a FOR-loop variable directly
ECHO For_variable "%%~I"
rem set a FOR-loop variable as an environment variable value
set "_myVar=%%~I" see tilde which would strip double quotes
rem process an environment variable INside a FOR-loop body
SETLOCAL EnableDelayedExpansion
echo Env_variable "!_myVar!"
ENDLOCAL
rem process an environment variable OUTside a FOR-loop body
call :ProcessMyVar
)
ENDLOCAL
goto :eof
:ProcessMyVar
rem process an environment variable OUTside a FOR-loop body
echo Env_var_Call "%_myVar%"
goto :eof
Output shows that even names with cmd-poisonous characters like percent or exclamation (etc. etc.) are processed properly:
==> tree "%UserProfile%\Music"
Folder PATH listing
Volume serial number is 0000005F F2DF:F89D
C:\USERS\USER\MUSIC
├───100% My Tunes!
└───My Songs!
==> D:\bat\SO\39697872.bat
For_variable "100% My Tunes!"
Env_variable "100% My Tunes!"
Env_var_Call "100% My Tunes!"
For_variable "My Songs!"
Env_variable "My Songs!"
Env_var_Call "My Songs!"
==>
Resources (required reading, incomplete):
(command reference) An A-Z Index of the Windows CMD command line
(helpful particularities) Windows CMD Shell Command Line Syntax
(%I, %~I etc. special page) Command Line arguments (Parameters)
(special page) EnableDelayedExpansion
(>, & etc. special page) Redirection
(%% doubled percent sign, ^ caret, double quotes) Escape Characters, Delimiters and Quotes

batch rename multiple files in windows?

I wonder what's wrong with my coding, because it's not working
I want to rename all the png files inside Chris.
but it failed
for /f in ('C:/Users/Chris/Downloads/images/*.png')
do ren "C:\Users\Chris\Downloads\images\*.png" "%date:~10,4%-%date:~4,2%-%date:~7,2%_%HR%%time:~3,2%-img.png"
No need for /f in argument, no need for quotes but your missing a variable declaration
The variable should be used in the do-part otherwise the for is not realy helpful
the for will enumerate the full path so you need to strip the filename using ~n
the do-part must be directly behind the for-statement or it needs to be inside round brackets
here's the complete code:
for %%i in (C:/Users/Chris/Downloads/images/*.png) do (
ren "%%i" "%date:~10,4%-%date:~4,2%-%date:~7,2%_%HR%%time:~3,2%-%%~niimg.png"
)
If order to use a for loop, you need to specify a variable to use (even if you don't use a variable in the loop at all), otherwise you'll get a syntax error. While variables can only be one letter, this is pretty much the only time in batch that variables are case-sensitive, so you've got 52 letters, plus a few additional characters that I've seen used, like #. Additionally, do must always be on the same line as the ).
A for /F loop can process strings, text files, and other batch commands.
To process strings, use double quotes: for /F %%A in ("hello world") do echo %%A
To process batch commands, use single quotes: for /F %%A in ('dir /b') do echo %%A
To process text files, do not use any quotes at all: for /F %%A in (C:\Users\Chris\image_list.txt) do echo %%A
You may also want to go into the directory that you're processing just to make things easier.
pushd C:\Users\Chris\Downloads\images
for /F %%A in ('dir /b *.png') do (
REM I'm not sure what the %HR% variable is supposed to be, so I'm ignoring it.
ren "%%A" "%date:~10,4%-%date:~4,2%-%date:~7,2%_%HR%%time:~3,2%-img.png"
)

cmd for loop variable set issue

I have a file named like
HelfTool.txt
Code1=Value1
Code2=Value2
I am trying to get the variable named as Code1 and code 2 in cmd batch file with corresponding values. I have written below code but it gives me error stated below.
for /f tokens^=1^,^2^ delims^=^*^=^" %%b in (C:\HelfTool.txt) do if not defined "%%b" set "%%b"=%%c
Environment variable Code1 not defined
Environment variable Code2 not defined
I tried to define these variable at the beginning of the batch file but no use. Can anyone help here.
Your if not defined is wrong - the variable name should not be quoted. It should be
if not defined %%b
Your set command is wrong - it creates a variable with quotes in the name. It should be
set %%b=%%c
or better yet, enclose the entire assignment within one set of quotes:
set "%%b=%%c"
Your FOR /F options are mostly correct, but I do not understand why you took the difficult route of escaping a bunch of characters instead of simply using quotes. Also, I don't think you want to include * as a delimiter. You could have used
for /f "tokens=1,2 delims=="
or better yet (just in case the value contains an =, though it will not preserve a leading = in the value)
for /f "tokens=1* delims=="
But I don't see why you are parsing the line at all, or why you think you must test if the variable is defined yet. It seems to me you could simply use:
for /f "delims=" %%A in (C:\HelfTool.txt) do set "%%A"
Next CLI output could help:
==>for /f tokens^=1^,^2^ delims^=^*^=^" %b in (HelfTool.txt) do #echo set "%b=%c"
set "Code1=Value1"
set "Code2=Value2"
Another approach:
==>for /f "tokens=*" %b in (HelfTool.txt) do #echo set "%b"
set "Code1=Value1"
set "Code2=Value2"
Double the % (percent sign) to use in a .bat batch script, e.g. last command should be
for /f "tokens=*" %%b in (HelfTool.txt) do #echo set "%%b"

Resources