Reading a file with for statment - Batch - windows

I have this code:
#echo off
for /f "delims=" %%a in ("%~dp0\files\text\lead_r.txt") do set /p key= < lead_r.txt
ECHO %key%
PAUSE
What I want it to do is to open a specific text file, read it and then write what's in it to %key%. It works when lead_r.txt and the batch file are in the same folder but it fails when I move lead.txt to \files\text. There are no files with spaces in \files\text so i don't know where the problem is.
Thanks

Hard to understand your goal, but try next code snippet:
#echo off >Nul
setlocal EnableDelayedExpansion
for /f "delims=" %%a in ("%~dp0\files\text\lead_r.txt") do (
rem the same file in next line
rem set /p key=< lead_r.txt
set /p key= < %%a
ECHO !key!
PAUSE
)
endlocal
Here mind EnableDelayedExpansion keyword of setlocal command = Expand variables at execution time rather than at parse time, if used !key! syntax instead of %key% one.

Related

How to prevent empty space lines while iterating a .txt file using FOR loop in batch Script

I have one .txt file with text and some empty space lines. While doing some operations in .txt file by using for loop, found originally contained empty space lines are gone.
Example :
I have a temp.txt file with below input :
#
Require
#
#Rel task
#
HOST_ID=
ACTIVATE_ID
#
#
After doing some operations using FOR Loop I am getting result in same .txt file like below :
#
Require
#
#Rel task
#
HOST_ID=56767\Ether
ACTIVATE_ID
#
#
So, I don't want to ignore those empty space lines.
I tried to use usebacq keyword in for loop, but not working.
I tried each and possible way to do this, but failed everytime.
Here, is my code :
#echo off
setlocal enableextensions disabledelayedexpansion
set rem=56767\Ether
set "textFile=temp.txt"
for /f "delims=" %%i in ('type "%textFile%" ^& break ^> "%textFile%" ') do (
set "line=%%i"
setlocal enabledelayedexpansion
if !line!==HOSTID= (
set "foo=!line:HOSTID=HOSTID=%rem%!"
set "line=!foo:~0,-1!"
)
>>"%textFile%" echo(!line!
endlocal
)
:EXIT
pause
In above code, I am doing to append some extra string in front of provided string in same .txt file.
Here's an alternative method, the idea being that you don't need delayed expansion, and, (for safety), you're not trying to read from and write to the same file.
What it does is to first determine if your required string exists in the file, if it doesn't the script closes, if it does it sets a variable to its line number. Then the file is parsed outputting the contents of each line untouched except for the line matching the saved variable, where it appends %rem% to it.
When the script ends your original file should exist along side it with a .bak extension.
#Echo Off
SetLocal EnableExtensions
Set "rem=56767\Ether"
Set "textFile=temp.txt"
Set "lineNum="
For /F Delims^=: %%G In ('^""%__AppDir__%findstr.exe" /INR "\<HOST_ID=\>" "%textFile%" 2^>NUL^"')Do Set "lineNum=%%G"
If Not Defined lineNum GoTo :EOF
For %%G In ("%textFile%")Do Set "_=%%~nG.bak" & Copy /Y "%%G" "%%~nG.bak">NUL
(For /F "Tokens=1*Delims=:" %%G In ('^""%__AppDir__%findstr.exe" /N "^" "%_%"^"')Do If %%G NEq %lineNum% (Echo=%%H)Else Echo %%H%rem%)>"%textFile%"
Pause
I am not sure if your file has a space before HOST_ID= like it currently does, but both with/without space has been added in this example:
#echo off
setlocal enableextensions disabledelayedexpansion
set "rem=56767\Ether"
set "textFile=temp.txt"
for /f "tokens=1,* delims=[]" %%i in ('type "%textFile%" ^| find /v /n "" ^& break^>"%textFile%"') do (
set "line=%%j"
setlocal enabledelayedexpansion
if "!line!" == "HOST_ID=" set "line=!line!%rem%"
if "!line!" == " HOST_ID=" set "line=!line!%rem%"
echo(!line!
endlocal
)
:EXIT
pause
Delimiters are [] because we add line numbers which you do not see as [n] before each entry by using find /V /N "". This way we retain the empty lines.

Reading line by line from one file and write to another file using batch script

In below code i am tring to fetch the line no of string "AXX0000XXXA" from file data.txt,then fetching line by line and printing target.txt file,in between if the line reach the find line no i am adding one more line from file temp.txt.The code is working fine with the less nos of records(tested with 150 lines-File Size 100 kb),but when i am processing with 50K records(File Size 25MB) it is taking more then 25 minutes to process.could you please help me how i will process same in less time.
#echo off
setlocal enabledelayedexpansion
for /f "delims=:" %%a in ('findstr /n "AXX0000XXXA" "C:\Users\23456\Desktop\data.txt"') do (set find_line=%%a)
set /a counter=0
for /f "usebackq delims=" %%b in (`"findstr /n ^^ C:\Users\23456\Desktop\data.txt"`) do (
set curr_line=%%b
set /a counter=!counter!+1
if !counter! equ !find_line! (
type temp.txt >> target.txt
)
call :print_line curr_line
)
endlocal
:print_line
setlocal enabledelayedexpansion
set line=!%1!
set line=!line:*:=!
echo !line!>>target.txt
endlocal
Your code uses three Batch file constructs that are inherently slow: call command, >> append redirection and setlocal/endlocal, and these constructs are executed once per each file line! It would be faster to include the subroutine into the original code to avoid the call and setlocal commands, and an echo !line!>>target.txt command imply open the file, search for the end, append the data and close the file, so it is faster to use this construct: (for ...) > target.txt that just open the file once. An example of a code with such changes is in Compo's answer.
This is another method to solve this problem that may run faster when the search line is placed towards the beginning of the file:
#echo off
setlocal enabledelayedexpansion
for /f "delims=:" %%a in ('findstr /n "AXX0000XXXA" "C:\Users\23456\Desktop\data.txt"') do (set /A find_line=%%a-1)
call :processFile < "C:\Users\23456\Desktop\data.txt" > target.txt
goto :EOF
:processFile
rem Duplicate the first %find_line%-1 lines
for /L %%i in (1,1,%find_line%) do (
set /P "line="
echo !line!
)
rem Insert the additional line
type temp.txt
rem Copy the rest of lines
findstr ^^
exit /B
This should create target.txt with content matching data.txt except for an inserted line taken from tmp.txt immediately above the line matching the search string, AXX0000XXXA.
#Echo Off
Set "fSrc=C:\Users\23456\Desktop\data.txt"
Set "iSrc=temp.txt"
Set "sStr=AXX0000XXXA"
Set "fDst=target.txt"
Set "iStr="
Set/P "iStr="<"%iSrc%" 2>Nul
If Not Defined iStr Exit/B
Set "nStr="
For /F "Delims=:" %%A In ('FindStr/N "%sStr%" "%fSrc%" 2^>Nul') Do Set "nStr=%%A"
If Not Defined nStr Exit/B
( For /F "Tokens=1*Delims=:" %%A In ('FindStr/N "^" "%fSrc%"') Do (
If "%%A"=="%nStr%" Echo %iStr%
Echo %%B))>"%fDst%"
I have made it easy for you to change your variable data, you only need to alter lines 3-6.
I have assumed that this was your intention, your question was not clear, please accept my apologies if I have assumed incorrectly.

Change each line of text to each column of csv file

I have a text file. For example
This is computer
That one is monitor
Some products are printer
I want to save each line of data into each column of csv file as a one row.
So, I try to create a batch file like this.
#ECHO OFF
setlocal ENABLEDELAYEDEXPANSION
set file=a.txt
set content=
echo %file%
for /F %%i in (a.txt) Do (
set content=!content!,%%i
)
echo %content%>>result.csv
pause
But I get only the first word from every line of text.
When I try to add tokens=* to for loop,
for /F "tokens=*" %%i in (a.txt) Do....
I got the error: The system cannot find the file specified.
I'm not understand whats wrong with my code and I'm not familiar with batch script.
You need to ensure that your protecting spaces in your line content and file names:
#Echo Off
SetLocal EnableDelayedExpansion
Set "fIn=a.txt"
Set "fOut=result.csv"
Set "str="
For /F "UseBackQ Delims=" %%A In ("%fIn%") Do Set "str=!str!,%%A"
If Defined str >>"%fOut%" Echo(%str:~1%
Edit
A slight alternative to cater for some potential problematic characters which may exist in the not provided content of the file:
#Echo Off
SetLocal DisableDelayedExpansion
Set "fIn=a.txt"
Set "fOut=result.csv"
Set "str="
SetLocal EnableDelayedExpansion
For /F "UseBackQ Delims=" %%A In ("%fIn%") Do Set "str=!str!,%%A"
EndLocal & Set/P "=%str:~1%"<Nul>>"%fOut%"
There were several bugs in your code. I've fixed them so now a proper csv string is being generated. However, newer Excel versions actually use ; instead of , to separate cells. This is your code:
#ECHO OFF
setlocal ENABLEDELAYEDEXPANSION
set file=a.txt
for /F %%i in (%file%) Do (
set content=!content!;%%i
)
set content=!content:~1!
echo %content%>>result.csv
pause

Batch how to read a text file

I need to make a batch file that can read a text file and I am using windows 7 ultimate 32 bit
I am currently using this code:
#ECHO OFF
for /f "delims=" %%x in (test.txt) do set "Var=%%x"
ECHO %Var%
pause
But this only reads the first line and I need it to read the whole thing. I need it to display the full text file.
Try this:
#ECHO OFF
SetLocal EnableDelayedExpansion
for /f "delims=" %%x in ('type test.txt') do (
set "Var=%%x"
ECHO !Var!
)
pause
You need to enclose the for loop with brackets if you are performing multiple commands inside the for loop. Besides that, SetLocal EnableDelayedExpansion will helps to expand the variable at execution time rather than at parse time.
Hope this helps.
Actually, this should read the whole file and set Var to the last line.
If you need to process the whole file, you have several options:
If you just need to do something for every line, then just use a block instead of the set "Var=%%x":
for /f "delims=" %%x in (test.txt) do (
rem Do something with %%x
)
If you need the complete file line-by-line in memory, use a counter and emulate arrays with lots of variables:
setlocal enabledelayedexpansion
set cnt=0
for /f "delims=" %%x in (test.txt) do (
set "ine[!cnt!]=%%x"
set /a cnt+=1
)
set /a numlines=cnt-1
and afterwards you can just use a for /l loop to access them again.

How do I write a batch that is copying itself?

I'd like to write a batch file, which reads its own code inside a string, then creates a new batch file with the string as content and execute it.
You can read the content of the started batch file with
type "%~f0"
Therefore, try something like
echo off
type "%~f0" > Test\file.bat
Test\file.bat
However, this script would repeat itself continously (or aborts if the directory Test does not exist). So you need to think about this approach (i.e. using conditional statements).
#echo off
setlocal DisableDelayedExpansion
if not exist newBatchFile.bat (
echo First execution!
set "batchFile="
for /F "usebackq delims=" %%a in ("%~F0") do (
set "line=%%a"
setlocal EnableDelayedExpansion
if "!line:~0,1!" equ ")" set "batchFile=!batchFile:~0,-1!"
set "batchFile=!batchFile!!line!"
if "!line:~-1!" neq "(" set "batchFile=!batchFile!&"
for /F "delims=" %%b in ("!batchFile!") do endlocal & set "batchFile=%%b"
)
setlocal EnableDelayedExpansion
echo !batchFile:~0,-1! > newBatchFile.bat
newBatchFile.bat
) else (
echo Second execution!
)

Resources