Problem with nested FOR-Loop and IF-Condition - batch-file

I have some lines of text. Then I have a list with test-words. I like to look up each line of the text and check if one of the test-words appears in it.
Beforehand this works well with a commands like these:
IF not "!stringToTest:%searchstring%=!"=="!stringToTest!"
However, now this seems to be more complicated as I have nested Loops?
I try to create a little MWE for my problem:
#echo off
setlocal enabledelayedexpansion
set /a counterPC=0
set "listPC=Win10,Motherboard,USB-Port,Core"
FOR %%G in (%listPC%) do (
set PCsearchVal[!counterPC!]=%%G
set /a counterPC+=1
)
set /a counterPC-=1
set "dummyline=Environment,1234,ZUIOP,Core"
FOR %%G in (%dummyline%) do (
set "stringToTest=%%G"
echo String to Test: !stringToTest!
FOR /l %%I in (0,1,%counterPC%) do (
set "searchstring=!PCsearchVal[%%I]!"
echo Test for this String: !searchstring!
IF not "!stringToTest:%searchstring%=!"=="!stringToTest!" echo Searchstring is in String to Test
)
)
endlocal
pause
In this he alway enter the IF-Condition. I know that this can may be solved with FINDSTR however in all my other code I used the search-strategy liek above. There may be just a little mistake I oversee? Many thanks in advance-

Related

Windows Batch Files - Moving/Getting For Loop Variables

I'm trying to simply get the filenames from a directory into a loop and then process (with the eventual aim of then doing a substring on the filename), but can't get it to work.
I've googled plenty and it seems to me that what I'm doing should work, but I'm obviously missing something.
Here's my code:-
setlocal ENABLEDELAYEDEXPANSION
set files=*.*
FOR %%A IN ("%files%") DO (
echo %%A
Set MYVAR=%%A
echo MYVAR=%MYVAR%
)
pause
The echo of the %%A works fine, but MYVAR is always empty. I had this working
on 1 line earlier, before I added the brackets.
Please help. I've spent far too long on this already and am pulling my hair out.
Try using one of the two methods below.
Either:
#Echo Off
SetLocal EnableDelayedExpansion
Set "files=*.*"
For %%A In ("%files%") Do (
Echo=%%A
Set "MYVAR=%%A"
Echo=MYVAR=!MYVAR!
)
Timeout -1
Or:
#Echo Off
Set "files=*.*"
For %%A In ("%files%") Do (
Echo=%%A
Set "MYVAR=%%A"
Call Echo=MYVAR=%%MYVAR%%
)
Timeout -1

Replacing String in Batch file

I am having an bit of trouble in replacing an string insde an .txt file with Batch
What i have now is this
:SetHostName
set /p HostName=Please Enter your hostname:
setlocal enabledelayedexpansion
set oldstring=%FTP_HOST%
set newstring=%HostName%
for /f "tokens=*" %%i in (FTPConfig.ini) do (
set str=%%i
set str=!str: %oldstring% = "hi"!
echo !str!
)
But when i test it it wont replace the FTP_HOST instead it shows this
FTP_HOST=test
FTP_USER=hi
FTP_PASS=testing
FTP_PROGRAM_FOLDER=program
FTP_RESOURCE_FOLDER=resource
inside my .txt file i have this
FTP_HOST=test
FTP_USER=hi
FTP_PASS=testing
FTP_SERVER_FILE_LOCATION=program
FTP_SERVER_RESOURCE_LOCATION=resource
Any help would be appriciated
I think you have this quite backwards. This code appears to be trying to replace the actual text FTP_HOST, not the value that appears after it. If you fixed the obvious errors, you'd have:
set oldstring=FTP_HOST
set newstring=%HostName%
for /f "tokens=*" %%i in (FTPConfig.ini) do (
set str=%%i
set str=!str:%oldstring%=%newstring%!
echo !str!
)
Assuming I enter my.new.host, that would give the output:
my.new.host=test
FTP_USER=hi
FTP_PASS=testing
FTP_PROGRAM_FOLDER=program
FTP_RESOURCE_FOLDER=resource
I really don't think that's what you intended. What you probably wanted is something like this:
set oldstring=FTP_HOST
set newstring=%HostName%
for /f "tokens=1,2* delims==" %%i in (FTPConfig.ini) do (
set str=%%j
if "%%i"=="%oldstring%" set str=%newstring%
echo %%i=!str!
)
Which yields:
FTP_HOST=my.new.host
FTP_USER=hi
FTP_PASS=testing
FTP_PROGRAM_FOLDER=program
FTP_RESOURCE_FOLDER=resource

Trying to reformat a very large csv with a batch file

I have an application that exports data in the format:
1a,1b,1c1,1c2,1c3, ... (up to 1c100),1d1,1d2,1d3, ... (up to 1d100)
2a,2b,2c1,2c2,2c3, ... (up to 2c100),2d1,2d2,2d3, ... (up to 2d100)
etc.
and I am trying to reformat this into
1a,1b,1c1,1d1
1a,1b,1c2,1d2
.
.
1a,1b,1c100,1d100
2a,2b,2c1,2d1
2a,2b,2c2,2d2
etc.
I figured that if this can be done a row at a time I can just loop through the file. However I can't find a way of doing a single row with either tokens, a list, or even as a string function. There is too much data to process in a single operation (each value is about 12 chars). Tokens limit at (roughly) 64/202, a list at about 107/202 and a string at about 1000/2300
Does anyone know how this can be written into a new file?
I was trying things like:
#echo off
setlocal enableDelayedExpansion
set dimCnt=0
<example.csv (
set /p "dimList=" >nul
for %%D in (!dimList!) do (
set /a dimCnt+=1
set "dim[!dimCnt!]=%%D"
)
)
echo
for /l %%I in (3 1 102) do echo !dim[1]!,!dim[2]!,!dim[%%I]!
</code>
..besides the fact that I have missed out the last variable in the line (need to add 100 to it), I can't get more than about 80-110 values out of the list (I guess it depends on value string length)
#echo off
setlocal enableextensions enabledelayedexpansion
(for /f "tokens=1,2,* delims=," %%a in (example.csv) do (
set "data=%%c"
set "i=0"
for %%f in ("!data:,=" "!") do (
set /a "i+=1"
set "d[!i!]=%%~f"
)
set /a "end=!i!/2"
set /a "j=!end!+1"
for /l %%i in (1 1 !end!) do (
for %%j in (!j!) do echo %%a,%%b,!d[%%i]!,!d[%%j]!
set /a "j+=1"
)
)) > output.csv
endlocal
This iterates over the file, getting the first two tokens in the line (%%a and %%b), the rest of the line (%%c) is splitted and each value stored in an environment variable array (kind of). Then, the array is iterated from the start and from the middle, reading the needed values to append to %%a and %%b and generating output file.
#ECHO OFF
SETLOCAL
(
FOR /f "tokens=1,2,*delims=," %%a IN (u:\long.csv) DO (
SET rpta=%%a
SET rptb=%%b
CALL :rptcd %%c
)
)>newfile.txt
GOTO :EOF
:rptcd
SET /a lines=100
SET lined=%*
FOR /l %%x IN (1,1,99) DO CALL SET lined=%%lined:*,=%%
:loop
IF %lines%==0 GOTO :EOF
SET /a lines-=1
CALL SET lined=%lined:*,=%
FOR /f "delims=," %%x IN ("%lined%") DO ECHO %rpta%,%rptb%,%1,%%x&shift&GOTO loop
GOTO :eof
This should get you going - just need to change the input filename and output filename...
Your code does not work because SET /P cannot read more than 1023 bytes. At that point it returns the data read so far, and the next SET /P picks up where it left off. Adapting your code to compensate will be very difficult. You would be better off using FOR /F as in MC ND's answer. But beware, batch has a hard limit of 8191 characters per line in pretty much all contexts.
Better yet, you could use another scripting language like JScript, VBS, or PowerShell. Performance will be much better, and the code much more robust and far less arcane. I love working with batch, but it simply is not a good text processing language.

not able to read characters of a string inside a for loop

Am trying to read characters of a string inside a for loop.
The command !string:~1,3! works fine. But can I do this with variables instead of 1 and 3. I tried the following code, but I don't know what is wrong. Its not working.
#echo off
setlocal enableextensions enabledelayedexpansion
set string=abcdefghij
set /a count=1
for /l %%x in (1,1,3) do (
set string2=!string:~%count%,1!
set /a count+=1
echo !string2!
pause
)
but It always gives the output as:
b
I want the output to be as:
b
c
d
Kindly help in solving this.. A big thanks in advance
In order to achieve what you want, you need to do a Delayed Expansion twice, that is, something like this:
set string2=!string:~!count!,1!
Of course, previous line is invalid. Although there are several ways to solve this problem, most of they use call command that is slow. To fix this problem so it run in the fastest way use a for command to change the first !count! expansion into a FOR replaceable parameter, and then use it in the original expression:
for %%i in (!count!) do set string2=!string:~%%i,1!
The problem is that the expansion of %count% isn't delayed, so it has the same value for every loop iteration. It's better written like this:
#echo off
setlocal enableextensions enabledelayedexpansion
set string=abcdefghij
set /a count=1
for /l %%x in (%count%,1,3) do (
set string2=!string:~%%x,1!
echo !string2!
)
Edit
If you want to keep %count% evaluated as the variable is set and not just at the beginning of the for loop, use Aacini's answer.

Batch - Read contents of a file in an array

I've a text file with two rows (say param.txt) which is shown below:
Mar2012
dim1,dim2,dim3,dim4
I want to read this file in batch and store the contents of first line in a variable called cube_name. When I'm reading the second line, I want to split the comma delimited string dim1,dim2,dim3,dim4 and create an array of four elements. I am planning to use the variable and the array in later part of the script.
The code which I created is shown below. The code is not working as expected.
#echo off & setlocal enableextensions enabledelayedexpansion
set /a count_=0
for /f "tokens=*" %%a in ('type param.txt') do (
set /a count_+=1
set my_arr[!count_!]=%%a
)
set /a count=0
for %%i in (%my_arr%) do (
set /a count+=1
if !count! EQU 1 (
set cube_name=%%i
)
if !count! GTR 1 (
set dim_arr=%%i:#=,%
)
)
for %%i in (%dim_arr%) do (
echo %%i
)
echo !cube_name!
I get to see the following when I run the code:
C:\Working folder>test2.bat
ECHO is off.
So this doesn't appear to work and I can't figure out what I'm doing wrong. I am fairly new to the batch scripting so help is appreciated
Your first FOR loop is OK. It is not how I would do it, but it works. Everything after that is a mess. It looks like you think arrays are a formal concept in batch, when they are not. It is possible to work with variables in a way that looks reminiscent of arrays. But true arrays do not exist within batch.
You use %my_arr% as if it is an array, but my_arr is not even defined. You have defined variables my_arr[1] amd my_arr[2] - the brackets and number are part of the variable name.
It also looks like you have a misunderstanding of FOR loops. I suggest you carefully read the FOR documentation (type HELP FOR from a command line). Also look at examples on this and other sites. The FOR command is very complicated because it has many variations that look similar to the untrained eye, yet have profoundly different behaviors. One excellent resource to help your understanding is http://judago.webs.com/batchforloops.htm
Assuming the file always has exactly 2 lines, I would solve your problem like so
#echo off
setlocal enableDelayedExpansion
set dimCnt=0
<param.txt (
set /p "cube_name=" >nul
set /p "dimList=" >nul
for %%D in (!dimList!) do (
set /a dimCnt+=1
set "dim[!dimCnt!]=%%D"
)
)
echo cube_name=!cube_name!
for /l %%I in (1 1 !dimCnt!) do echo dim[%%I]=!dim[%%I]!
One nice feature of the above solution is it allows for a varying number of terms in the list of dimensions in the 2nd line. It will fail if there are tabs, spaces, semicolon, equal, * or ? in the dimension names. There are relatively simple ways to get around this limitation if need be.
Tabs, spaces, semicolon and equal can be handled by using search and replace to enclose each term in quotes.
for %%D in ("!dimList:,=","!") do (
set /a dimCnt+=1
set "dim[!dimCnt!]=%%~D"
)
I won't post the full solution here since it is not likely to be needed. But handling * and/or ? would require replacing the commas with a new-line character and switching to a FOR /F statement.
I'm impressed of your code!
Do you try to debug or echo anything there?
You could simply add some echo's to see why your code can't work.
#echo off & setlocal enableextensions enabledelayedexpansion
set /a count_=0
for /f "tokens=*" %%a in ('type param.txt') do (
set /a count_+=1
set my_arr[!count_!]=%%a
)
echo ### show the variable(s) beginning with my_arr...
set my_arr
echo Part 2----
set /a count=0
echo The value of my_arr is "%my_arr%"
for %%i in (%my_arr%) do (
set /a count+=1
echo ## Count=!count!, content is %%i
if !count! EQU 1 (
set cube_name=%%i
)
if !count! GTR 1 (
echo ## Setting dim_arr to "%%i:#=,%"
set dim_arr=%%i:#=,%
echo
)
)
for %%i in (%dim_arr%) do (
echo the value of dim_arr is "%%i"
)
echo cube_name is "!cube_name!"
Output is
### show the variable(s) beginning with my_arr...
my_arr[1]=Mar2012
my_arr[2]=dim1,dim2,dim3,dim4
Part 2----
The value of my_arr is ""
cube_name is ""
As you can see your part2 fails completly.

Resources