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.
Related
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
I have some code in which I want to use a FOR loop to handle a set of files.
As part of handling a file there's a FOR /F loop that reads it and appends data to an other file based on the file name.
In order to be able to set the output file name I have delayed variable expansion set on.
This is what the code should look like as I originally intended it to be:
setlocal enabledelayedexpansion
for %%f in (DataFolder\*.Ext) do (
set POI=%%~f
set POI=!JbPOI:DataFolder\=!
set POI=!JbPOI:.Ext=!
for /f "tokens=1,2,3 delims=," %%a in ("%%~f") do (
set CX=%%a
set CY=%%b
set FN=%%c
echo !FN!,9,!CX!,!CY! >> "DataFolder\!POI!.tmp"
)
)
endlocal
This code doesn't work because variable %%a, %%b and %%c never receive a value, %%a always has the same value as %%f.
I have read some articles about this issue but couldn't extract a solution from them that worked.
I have tried several things, none worked so far...
added a dummy outer loop to create variable %%a through %%j explicitly
inner FOR loop taken out and made it a subroutine
inner FOR loop taken out and made it a separate batch file
Can anybody please tell me how this can - or must - be solved?
setlocal enabledelayedexpansion
for %%f in (DataFolder\*.Ext) do (
set POI=%%~f
set POI=!JbPOI:DataFolder\=!
set POI=!JbPOI:.Ext=!
for /f "useback tokens=1,2,3 delims=," %%a in ("%%~f") do (
set CX=%%a
set CY=%%b
set FN=%%c
echo !FN!,9,!CX!,!CY! >> "DataFolder\!POI!.tmp"
)
)
endlocal
I'm not sure if you want to read the file "%%~f" , but I think this is what you need.
Sorry, but for the posted code i don't see the need for delayed expansion. All the needed data is being directly retrieved from the for replaceable parameters
setlocal enableextensions disabledelayedexpansion
for %%f in (DataFolder\*.Ext) do (
(
for /f "usebackq tokens=1-3 delims=," %%a in ("%%~f") do echo(%%c,9,%%a,%%b
) > "DataFolder\%%~nf.tmp"
)
endlocal
If the real code includes something not posted, maybe the answer from npocmaka will better fit in the problem.
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.
I have a batch file to Find and replace text string in a file with a portion of the its own file-name in multiple files within a folder using windows Batch script but it does not work and simply replace YYY with null or nothing. Any help appreciated. thank you
#echo off
SETLOCAL
SET stringtofindreplace=YYY
for %%f in (*.fmw) do (
#echo Processing %%f...
fOR /F "delims=" %%l IN (%%f) DO (
SET "line=%%l"
SET fname=%%~nf
SET fname=!fname:~6,3!
SETLOCAL ENABLEDELAYEDEXPANSION
set "x=!line:%stringtofindreplace%=%fname%!"
echo(!x!
ENDLOCAL)
)>%%~nf.txt
)
GOTO:EOF
here is updated code that still does not work
#echo off
SETLOCAL
SET stringtofindreplace=YYY
for %%f in (*.fmw) do (
#echo Processing %%f...
(
fOR /F "delims=" %%l IN (%%f) DO (
SET "line=%%l"
SET fname=%%~nf
SETLOCAL ENABLEDELAYEDEXPANSION
SET fname=!fname:~6,3!
SET "x=!line:%stringtofindreplace%=%fname%!"
echo(!x!
ENDLOCAL
)
)>%%~nf.txt
)
GOTO:EOF
You have a number of problems.
1) Your name substring computation attempts to use delayed expansion within your loop before you enable it.
2) The computed replacement string cannot be expanded using normal expansion. You need delayed expansion there as well. But you cannot use delayed expansion within delayed expansion. The trick is to transfer the inner value to a FOR variable.
3) You have got an extra, unbalanced ) after ENDLOCAL. I don't think it is causing any problems with the code you have posted, but you probably should remove it.
You are also computing the name substring once for every line, when it really only need be done once per file. This isn't a bug, but it is inefficient.
Here is corrected code.
#echo off
setlocal
set stringtofindreplace=YYY
for %%f in (*.fmw) do (
#echo Processing %%f...
setlocal enableDelayedExpansion
set "fname=%%~nf"
for /f "eol=: delims=" %%A in ("!fname:~6,3!") do (
endlocal
for /f "delims=" %%l IN (%%f) do (
set "line=%%l"
setlocal enableDelayedExpansion
set "x=!line:%stringtofindreplace%=%%A!"
echo(!x!
endlocal
)
)>"%%~nf.txt"
)
You still could have problems if any lines begin with ;. Also, empty lines will be stripped. Both limitations could be solved with a bit more code.
But even if you fix the limitations, it will be quite slow. It could be painfully slow if any files are large.
The code is much simpler, faster, and more reliable if you use my hybrid JScript/batch REPL.BAT utility:
#echo off
setlocal
set stringtofindreplace=YYY
for %%f in (*.fmw) do (
#echo Processing %%f...
setlocal enableDelayedExpansion
set "fname=%%~nf"
type "!fname!.fmw"|repl "%stringtofindreplace%" "!fname:~6,3!" li >"!fname!.txt"
endlocal
)
I would like to iterate a flat text file containing a Windows directory listing and run multiple commands against each line assigning each line to a variable. I then want to echo each resulting output from each command into a comma-delimited file. Yes, I understand batch programming might not be the best choice but am somewhat limited at the moment. Here is where I am at with it:
#echo off
setlocal
SETLOCAL ENABLEDELAYEDEXPANSION
:: There could be spaces in the filename, thus using delims
FOR /f "delims=?" %%a in (e:\multiline_textfile.txt) do (
set filename=%%a
CALL :PROG1
CALL :PROG2
CALL :PROG3
CALL :ENDPROG
:PROG1
FOR /f "delims=?" %%h in ('e:\apps\exe1.exe -s "!filename!"') do set result11=%%h
:PROG2
FOR /f "delims=?" %%i in ('e:\apps\exe1.exe -b"!filename!"') do set result2=%%i
:PROG3
FOR /f "delims=?" %%j in ('e:\apps\exe2.exe -c "!filename!"') do set result3=%%j
:ENDPROG
echo !result1!,!result2!,!result3!
)
---
Any insight would be greatly appreciated.
#echo off
SETLOCAL ENABLEDELAYEDEXPANSION
:: There could be spaces in the filename, thus using delims
FOR /f "delims=" %%a in (e:\multiline_textfile.txt) do (
set "filename=%%a"
CALL :PROG1
CALL :PROG2
CALL :PROG3
CALL :ENDPROG
)
echo here endeth your batch mainline
goto :eof
:PROG1
FOR /f "delims=" %%h in ('e:\apps\exe1.exe -s "!filename!"') do set "result1=%%h"
goto :eof
:PROG2
FOR /f "delims=" %%i in ('e:\apps\exe1.exe -b"!filename!"') do set "result2=%%i"
goto :eof
:PROG3
FOR /f "delims=" %%j in ('e:\apps\exe2.exe -c "!filename!"') do set "result3=%%j"
goto :eof
:ENDPROG
echo !result1!,!result2!,!result3!
goto :eof
You don't need the initial SETLOCAL - one is quite sufficient.
Labels are simply MARKERS in a batch program - they don't affect flow. The most common way to return in a CALLed routine is to GOTO :EOF where the colon is REQUIRED and the label :EOF is implicit and should NOT be declared.
Bad idea to attempt to use labels within a FOR loop like that. Might work with later versions, but not with earlier. Note the FOR loop's ending ) has been moved...
Whereas !var! works, it is not necessary in this case because each subroutine is essentially a whole new program which inherits the main environment as it stood at the CALL. Hence each !var! could be replaced by %var% and the SETLOCAL ENABLEDELAYEDEXPANSION need only be a SETLOCAL. You only need to use delayedexpansion where an ordinary environment variable's value is to be used after being changed in a compound statement (like a FOR over multiple lines, for instance)