Batch file for loop fails to execute inside for loop - batch-file

the task is simple to take input from the file "input.txt" which contains the keyword that need to be replace in the source file "source.txt" and create the newfile with the name of the keyword. Could you please suggest what is wrong.
#echo off &setlocal
setlocal enableextensions disabledelayedexpansion
set "search=POP"
set "source=dev500_ABC_eu.env"
for /f %%a in (input.txt) do (
set "replace=%%a"
set "newfile=devga520_%replace%_eu.env"
for /f "delims=" %%i in (%textfile%) do (
set "line=%%i"
setlocal enabledelayedexpansion
set "line=!line:%search%=%replace%!"
echo(!line!
endlocal
)>"%newfile%"
)
Here in the input.txt, suppose it has "PQR". So it should replace "POP" in the file with "PQR" and the new file shoud generate with the name dev500_PQR_eu.env
Input file.txt
line 1 --> PQR
line 2 --> XYX
line 3 --> NOB
line 4 --> BOB
Output expected: 4 different files after replacing the character "ABC" with the input file text eg: whereevr "ABC" is there it should be replaced by PQR inside the dev500_ABC_eu.env and the newfile to be renamed with the text.
dev500_PQR_eu.env --> replaced name and content as well by PQR.
dev500_XYX_eu.env
dev500_NOB_eu.env
dev500_BOB_eu.env
Any help will be appreciated. Thanks.

...
set "source=dev500_ABC_eu.env"
for /f %%a in (input.txt) do (set "replace=%%a")
set "newfile=devga520_%replace%_eu.env"
(
for /f "delims=" %%i in (%textfile%) do (
set "line=%%i"
setlocal enabledelayedexpansion
set "line=!line:%search%=%replace%!"
echo(!line!
endlocal
)
)>"%newfile%"
Please see delayed expansion items on SO for more info. Any %var% within a code block (parenthesised series of lines) will be replaced by the value of var at the time the block is first encountered.
You need to set replace outside of the block.
Your revision has clarified matters.
#ECHO Off
SETLOCAL
SET "search=POP"
set "source=dev500_ABC_eu.env"
:: This is a replacement source file I used for testing...
set "source=c:q45416169_1.txt"
for /f %%a in (c:q45416169.txt) do (
set "replace=%%a"
set "newfile=devga520_%%a_eu.env"
CALL DEL %%newfile%% >NUL 2>nul
for /f "delims=" %%i in (%source%) do (
set "line=%%i"
setlocal enabledelayedexpansion
set "line=!line:%search%=%%a!"
>>!newfile! echo(!line!
endlocal
)
)
I used a file named q45416169.txt containing your data for my testing.
I used a file named q45416169_1.txt containing some dummy text data for my testing.
I left the assignment of replace in the code, but it's now redundant.

Related

Batch (CMD) Iterate over two arrays (made out of 2 .txt files)

I would like to make a script that given 2 .txt files, it creates N files named as the values inside the first .txt file, and insert in that file the value inside the second .txt file.
[FILE_1].txt
name_1
name_2
name_3
name_4
[FILE_2].txt
text_1
text_2
text_3
text_4
Result:
name_1.html (with inside the string "text_1")
name_2.html (with inside the string "text_2")
name_3.html (with inside the string "text_3")
name_4.html (with inside the string "text_4")
In order to take the values inside the .txt file I use:
setlocal EnableDelayedExpansion
set i=0
for /F %%a in (file_1.txt) do (
set /A i+=1
set array[!i!]=%%a
)
set n=%i%
set s=0
for /F %%a in (file_2.txt) do (
set /A s+=1
set array[!s!]=%%a
)
set v=%s%
endlocal
(I know the number of elements in each file (they are the same))
How would you do it? I tried a lot of variations, with no success, like:
for /F %%a in (file_2.txt) do (
for /l %%v in (1, 1, 92) do (
echo %%~nxa
)>> %%~nxv.html
)
...
set array{!s!}=%%a
...
To create array{*} instead of array[*]
Then
for /L %%v in (1,1,%s%) do >"!array[%%v]!.html" echo !array{%%v}!
Of course, you could also call the arrays something bizarre like names and texts for instance and use the same type of brackets, but I'd be tempted to use name:%%i and text:%%s to avoid the brackets completely. (: because it can't exist within a filename) name_%%i and text_%%s to avoid the brackets completely. (: didn't work properly, changed to _ that worked; Other unlikely-to-start-a-line characters like ] would no doubt also work)
---- [actual test code]
#ECHO OFF
SETLOCAL ENABLEDELAYEDEXPANSION
rem The following settings for the source directory, destination directory, target directory,
rem batch directory, filenames, output filename and temporary filename [if shown] are names
rem that I use for testing and deliberately include names which include spaces to make sure
rem that the process works using such names. These will need to be changed to suit your situation.
SET "sourcedir=u:\your files"
SET "destdir=u:\your results"
SET "filename1=%sourcedir%\q65556186.txt"
SET "filename2=%sourcedir%\q65556186_2.txt"
set i=0
for /F "usebackq" %%a in ("%filename1%") do (
set /A i+=1
set array[!i!]=%%a
)
set n=%i%
set s=0
for /F "usebackq" %%a in ("%filename2%") do (
set /A s+=1
set array{!s!}=%%a
)
for /L %%v in (1,1,%s%) do >"%destdir%\!array[%%v]!.html" echo !array{%%v}!
TYPE "%destdir%\*.html"
GOTO :EOF
[results]
u:\your results\name_1.html
text_1
u:\your results\name_2.html
text_2
u:\your results\name_3.html
text_3
u:\your results\name_4.html
text_4
[with changes to code for naming purposes]
#ECHO OFF
SETLOCAL ENABLEDELAYEDEXPANSION
rem The following settings for the source directory, destination directory, target directory,
rem batch directory, filenames, output filename and temporary filename [if shown] are names
rem that I use for testing and deliberately include names which include spaces to make sure
rem that the process works using such names. These will need to be changed to suit your situation.
SET "sourcedir=u:\your files"
SET "destdir=u:\your results"
SET "filename1=%sourcedir%\q65556186.txt"
SET "filename2=%sourcedir%\q65556186_2.txt"
set i=0
for /F "usebackq" %%a in ("%filename1%") do (
set /A i+=1
set names_!i!=%%a
)
set n=%i%
set s=0
for /F "usebackq" %%a in ("%filename2%") do (
set /A s+=1
set texts_!s!=%%a
)
for /L %%v in (1,1,%s%) do >"%destdir%\!names_%%v!.html" echo !texts_%%v!
TYPE "%destdir%\*.html"
GOTO :EOF
[Same results]
You could probably do it like this:
#SetLocal EnableExtensions EnableDelayedExpansion
#(For /F UseBackQ^ Delims^=^ EOL^= %%G In ("[FILE_1].txt") Do 1> "%%G.html" (Set /P "}="&Echo(!}!)) 0< "[FILE_2].txt"

Loop through files in folder, replace content and Save as new Name

I need to loop through filed end with .edi in my folder, replace a character in the content and then save the file in another folder with "_updated"on the end.
e.g.
C:/Test/FileName.edi replace ' in file with ^ and save the file into C:/Test/Output/FileName_Updated.edi
I've tried the following code and it works up until the saving the filename part, I've got confused somewhere, I don't usually write batch scripts:
#echo off
setlocal enabledelayedexpansion
for %%f in (C:\Test\*.edi) do (
set "input=C:\Test\"
SET "output=C:\Test\Output\"
for %%a in (%%f) do (
set "output=%output%%%~na_update.%%~xa"
)
(for /f "delims=" %%i in (%%f) do (
set "line=%%i"
setlocal enabledelayedexpansion
set "line=!line:'=^!"
echo(!line!
endlocal
)))>> %output%
)
Figured it out with help from aschipfl
#echo off
setlocal enabledelayedexpansion
for %%f in (C:\Users\CHRW\Desktop\EDILocalTest\*.edi) do (
SET "output=C:\Users\CHRW\Desktop\EDILocalTest\Output\"
for %%a in (%%f) do (
set "outputfile=!output!%%~na_update%%~xa"
)
(for /f "delims=" %%i in (%%f) do (
set "line=%%i"
setlocal enabledelayedexpansion
set "line=!line:'=^!"
echo(!line!
endlocal
))>> !outputfile!
)
#echo off
setlocal enabledelayedexpansion
for %%f in (C:\Test\*.edi) do (
set "input=C:\Test\"
SET "output=C:\Test\Output\"
(for /f "delims=" %%i in (%%f) do (
set "line=%%i"
rem setlocal enabledelayedexpansion
set "line=!line:'=^!"
echo(!line!
rem endlocal
)))>> "%output%%%~nf_update.%%~xf"
)
Since you were changing the value of output within the loop, the redirection should have been to !output! not %output% - the changed value of output, not the value of output at the time the outer for loop was parsed.
Since %%f contains a filename, there's no need to re-parse it. Easier to construct the output filename in-line
Since delayedexpansion has been invoked at the start of the procedure, there's no need to re-invoke it and close the new invocation. I've REMmed-out those lines as it may be that you are presenting abbreviated code.

Batch file to rewrite txt file starting from last line

lets say that i have test.txt with this lines
1
2
3
i need batch file to rewrite this file as
3
2
1
in new txt file
i tried this to copy last line
for /f "delims=" %%A in (ttt.txt) do set last=%%A
echo %last%>>ttt_lastline.txt
and this to delete last line
#echo off & setlocal EnableDelayedExpansion
set row=
for /F "delims=" %%j in (File.txt) do (
if defined row echo.!row!>> File.new
set row=%%j
)
but wasn't helpful
#ECHO OFF
SETLOCAL ENABLEDELAYEDEXPANSION
SET "destdir=U:\destdir"
SET "filename1=100lines.txt"
SET "outfile=%destdir%\outfile.txt"
SET /a count=0
FOR /f "delims=" %%a IN (%filename1%) DO (
SET /a count+=1
SET "line[!count!]=%%a"
)
(
FOR /L %%a IN (%count%,-1,1) DO ECHO(!line[%%a]!
)>"%outfile%"
GOTO :EOF
You would need to change the setting of destdir to suit your circumstances.
I used a file named 100lines.txt containing some dummy data for my testing.
Produces the file defined as %outfile%
Using delayedexpansion, read each line into line[?] using !count!, then simply echo each line loaded in reverse order.
This is a Vbscript solution.
Create a file named reverse.vbs and use this as the code.
Dim Stack: Set Stack = CreateObject("System.Collections.Stack")
Do While Not WScript.StdIn.AtEndofStream
Stack.Push WScript.StdIn.ReadLine
Loop
WScript.StdOut.WriteLine Join(Stack.ToArray, vbCrLf)
Now to reverse your file execute this from a cmd prompt or a batch file.
type input.txt |cscript //nologo Reverse.vbs>>output.txt
#echo off
setlocal enabledelayedexpansion
for /f %%a in (forward.txt) do
(
set reversed=%%a !reversed!
)
for %%i in (!reversed!) do echo.%%i >> reversed.txt
goto :eof

Generic Text Converter

I want to make a generic batch script which will read a schema file which will contain the various width's/column length's of the fixed width flat file source and finally create a target csv file based on the column length.
Example:
Schema.txt
COL1,5
COL2,2
COL3,4
COL4,3
COL5,6
So the above schema.txt file contains the column list.It also contains the width of each field. Our source will always be a fixed width flat file. Our objective will be to convert it into csv.
Source1.txt
11111223333444555555
11111223333444555555
Target1.txt
11111,22,3333,444,555555
11111,22,3333,444,555555
Source2.txt
11111 333344466666
11111223333 66666
Target2.txt
11111,,3333,444,66666
11111,22,333,,66666
so it should be able to handle space and blanks as well, as we saw in 2nd Source file.
The schema should be a dynamic file where if we provide the structure the bat file will create a csv exactly like the structure from the source.The final target file should have the header taken from the schema file.
Please help.
My present code is given below:
echo off
setlocal EnableDelayedExpansion
echo a,b,c final.txt
rem replace the €€€ string with any unused one
set "fooString=€€€"
for /f "tokens=1 delims=;" %%i in (source.txt) do (
set "x=%%i"
for /f "tokens=1,2 delims=," %%a in (config.txt) do (
call SET "VARraw=!x:~%%a,%%b!%fooString%"
rem replaced with respect to the OP's comment: for %%p in (!VARraw!) do (
for /F "tokens=*" %%p in ("!VARraw!") do (
set "rav=%%p"
set "var=!rav:%fooString%=!"
echo/|set /p "=!var!,"
) final.txt
)
)
Present config.txt contains
0,9
9,3
12,11
23,7
30,1
But i want to modify it.Want to keep only the Field name and the width. Not the starting position and the width.
Problem with existing code is that it prints the result in one single line but i want the \n after the end of each line.
#echo off
setlocal EnableDelayedExpansion
rem Load the schema
set /A numCol=0, maxSpc=0
set "header="
set "spaces="
for /F "tokens=1,2 delims=," %%a in (Schema.txt) do (
set /A numCol+=1
set "header=!header!,%%a"
set "col[!numCol!]=%%b"
if %%b gtr !maxSpc! (
set /A spc=%%b-maxSpc, maxSpc=%%b
for /L %%i in (1,1,!spc!) do set "spaces=!spaces! "
)
)
rem Process the input file
echo %header:~1%
for /F "delims=" %%a in (%1) do (
set "in=%%a"
set "start=0"
set "out="
for /L %%i in (1,1,%numCol%) do for /F "tokens=1,2" %%j in ("!start! !col[%%i]!") do (
set "col=!in:~%%j,%%k!"
if "!col!" equ "!spaces:~0,%%k!" set "col="
set "out=!out!,!col!"
set /A start+=%%k
)
echo !out:~1!
)
Output of example session:
C:\> type Schema.txt
COL1,5
COL2,2
COL3,4
COL4,3
COL5,6
C:\> type Source1.txt
11111223333444555555
11111223333444555555
C:\> test Source1.txt
COL1,COL2,COL3,COL4,COL5
11111,22,3333,444,555555
11111,22,3333,444,555555
C:\> type Source2.txt
11111 333344466666
11111223333 66666
C:\> test Source2.txt
COL1,COL2,COL3,COL4,COL5
11111,,3333,444,66666
11111,22,3333,,66666
The following script (let us call it convert.bat) converts a text file given via command line argument into a CSV file according to your requirements. You may provide the result file as a second argument; if omitted, the output is displayed at the console. The default schema file Schema.txt can be changed if a third argument is specified: (so use like: convert.bat source.txt [target.txt [schema.txt]])
#echo off
setlocal EnableExtensions DisableDelayedExpansion
rem Remove leading blanks of every field if this value is non-empty:
set "DELBLANKS=REMOVE"
rem Specify source file as first command line argument:
set "SOURCE=%~1"
rem Specify target file as second argument (optionally):
set "TARGET=%~2"
rem Provide scheme file as third argument (default is "Schema.txt"):
set "SCHEME=%~3"
rem Check the given command line arguments:
if not defined SOURCE >&2 echo ERROR: no source file given! & exit /B 1
if not defined TARGET set "TARGET=con"
if not defined SCHEME set "SCHEME=%~dp0Schema.txt"
rem Read scheme file and build header:
setlocal EnableDelayedExpansion
set "HEADER="
set /A POSITION=0
set /A COLUMN=0
for /F "usebackq tokens=1,2 delims=," %%I in ("!SCHEME!") do (
set /A COLUMN+=1
set "HEADER=!HEADER!,%%I"
if not "%%J"=="" (
set "WIDTH=%%J"
set /A WIDTH[!COLUMN!]+=WIDTH
set /A POSITION[!COLUMN!]=POSITION
set /A POSITION+=WIDTH
)
)
rem Convert source file into CSV format and store to target file:
> "!TARGET!" (
echo(!HEADER:~1!
for /F usebackq^ delims^=^ eol^= %%L in ("!SOURCE!") do (
setlocal DisableDelayedExpansion
set "LINE=%%L"
setlocal EnableDelayedExpansion
set "LINE=!LINE:,=;!"
set "CSV="
for /L %%C in (1,1,%COLUMN%) do (
for /F "tokens=1,2 delims=," %%P in ("!POSITION[%%C]!,!WIDTH[%%C]!") do (
if defined DELBLANKS (
for /F tokens^=*^ eol^= %%S in ("!LINE:~%%P,%%Q!,") do (
for /F "delims=" %%T in (""!CSV!"") do (
endlocal
set "CSV=%%~T%%S"
setlocal EnableDelayedExpansion
set "LINE=!LINE:,=;!"
)
)
) else (
set "CSV=!CSV!!LINE:~%%P,%%Q!,"
)
)
)
if defined CSV echo(!CSV:~,-1!
endlocal
endlocal
)
)
endlocal
endlocal
exit /B
The headers in the schema file should not contain any exclamation marks !.
Any commas , in the source file will be replaced by semicolons ;.

Batch script to find and replace a string in text file without creating an extra output file for storing the modified file

I have written a batch script to find and replace a string in a text file. Following is my script.
#echo off &setlocal
set "search=%1"
set "replace=%2"
set "textfile=Input.txt"
set "newfile=Output.txt"
(for /f "delims=" %%i in (%textfile%) do (
set "line=%%i"
setlocal enabledelayedexpansion
set "line=!line:%search%=%replace%!"
echo(!line!
endlocal
))>"%newfile%"
del %textfile%
rename %newfile% %textfile%
I am able to replace the word successfully.
But i dont want to create Output.txt and then rename it the original file..
Please help me out for editing a text file without redirecting the output to a new file..
#echo off
setlocal enableextensions disabledelayedexpansion
set "search=%1"
set "replace=%2"
set "textFile=Input.txt"
for /f "delims=" %%i in ('type "%textFile%" ^& break ^> "%textFile%" ') do (
set "line=%%i"
setlocal enabledelayedexpansion
>>"%textFile%" echo(!line:%search%=%replace%!
endlocal
)
for /f will read all the data (generated by the type comamnd) before starting to process it. In the subprocess started to execute the type, we include a redirection overwritting the file (so it is emptied). Once the do clause starts to execute (the content of the file is in memory to be processed) the output is appended to the file.

Resources