Batch type file with variables - variables

i have a text file file.txt with the content:
%hello%
If i've set hello to "holi" is there any way I can type file.txt and resolve the variable content?
Maybe it's archivable piping to echo but
type file.txt | echo
Is not working for me.
Any help will be apreciated.
Thanks

Assuming there are no blank lines that need to be preserved
for /f usebackq^ delims^=^ eol^= %%A in ("yourFile.txt") do call echo(%%A
If there are blank lines, but no line begins with :, then
for /f "delims=: tokens=1*" %%A in ('findstr /n "^" "yourFile.txt"') do call echo(%%B
If there are blank lines, and some lines begin with :, and there are no ! literals
setlocal enableDelayedExpansion
for /f "delims=" %%A in ('findstr /n "^" "yourFile.txt"') do (
set "ln=%%A"
call echo(!ln:*:=!
)
If there are blank lines and some lines begin with :, and there are ! literals
for /f "delims=" %%A in ('findstr /n "^" "yourFile.txt"') do (
setlocal enableDelayedExpansion
set "ln=%%A"
call echo(!ln:*:=!
endlocal
)
All of the above use CALL, which slows things down considerably. The solution is faster if you put !hello! in your file instead of %hello%, and then you can rely on delayed expansion to expand the variable.
If no blank lines
setlocal enableDelayedExpansion
for /f usebackq^ delims^=^ eol^= %%A in ("yourFile.txt") do echo(%%A
If blank lines, but no line begins with :
setlocal enableDelayedExpansion
for /f "delims=: tokens=1*" %%A in ('findstr /n "^" "yourFile.txt"') do echo(%%B
If blank lines, and some lines begin with :
setlocal enableDelayedExpansion
for /f "delims=" %%A in ('findstr /n "^" "yourFile.txt"') do (
set "ln=%%A"
echo(!ln:*:=!
)

So I take it you want the contents of a file to be expanded just like variables.
Here you go:
>echo %hello%>file.txt
>type file.txt
%hello%
>set hello=holi
>type file.txt
%hello%
>for /f %f in (file.txt) do #echo %f
%hello%
>for /f %f in (file.txt) do #call echo %f
holi
>

Related

for /f loop "tokens and delimiters" didn't work with variables (batch file)

recently I was making a batch file I ran into a problem,
when I made a for /f loop, I used a variable in "tokens", like this example:
for /f "delims= tokens=!count2!" %%a in ('type test.txt 2^>nul') do (
like you can see, i have the variable !count2!, in the loop.
and when i tested it, it displayed !count2!" was unexpected at this time. And I dont know why?
can anyone help?
here is the full code of what I have tried:
#echo off
setlocal enableextensions enabledelayedexpansion
set "count1=0"
set "count2=0"
for /l %%b in (1 1 10) do (
set /a "count2+=1"
set /a "count1+=1"
for /f "delims= tokens=!count2!" %%a in ('type test.txt 2^>nul') do (
set "str!count1!=%%a"
)
)
echo !str1! !str2! !str3! !str4!
pause
by the way, test.txt contains test hello # ###
and, I want to set test, hello, # and ### as their own variable (str1, str2, str3 and str4).
and yes I have tried to do it with % instead of !
tell me if i wasn't clear enough!
thanks for all help :)
why bothering with tokens?
#echo off
setlocal enabledelayedexpansion
set /a count=0
for /f "delims=" %%i in (test.txt) do for %%j in (%%i) do (
set /a count+=1
set str!count!=%%j
)
set str

FINDSTR in FOR loop with variables as strings (Batch File)

It's my first post here, unfotrtunately question to you instead of help.
I'm writing small program which moves text and pdf files when string is found in text file.(1.txt, 1.txt.pdf ...) It was working very good when i had variables manually set in batch like this :
set c1=xxx
set p1=c:\test\xxx\
set c2=yyy
set p2=c:\test\yyy\
FOR /f "tokens=*" %%A IN ('FINDSTR /i /m "%c1%" "c:\test\*.txt"') DO (
IF "%ERRORLEVEL%"=="0" MOVE %%A "%p1%">nul
MOVE %%A.pdf %p1%
FOR /f "tokens=*" %%A IN ('FINDSTR /i /m "%c2%" "c:\test\*.txt"') DO (
IF "%ERRORLEVEL%"=="0" MOVE %%A "%p2%">nul
MOVE %%A.pdf %p2%
Now I'm trying to use input file with variables :
for /F "delims=^ tokens=1,2" %%A in (c:\test\db\input.cdb) do (
SET /A vidx=!vidx! + 1
set c!vidx!=%%A & set p!vidx!=%%B
It works good, but the problem starts when I try to use for loop for all this variables. Literally search for all (c1,c2,c3...) variables and move them to (p1,p2,p3,...) paths.
Input.cdb looks like this :
xxx ^ c:\test\xxx
yyy ^ c:\test\yyy
Code:
setlocal ENABLEDELAYEDEXPANSION
set vidx=0
for /F "delims=^ tokens=1,2" %%A in (c:\test\db\input.cdb) do (
SET /A vidx=!vidx! + 1
set c!vidx!=%%A & set p!vidx!=%%B
FOR /f "tokens=*" %%D IN ('FINDSTR /i /m "%c!vidx!%" "c:\test\*.txt"') DO (
IF "%ERRORLEVEL%"=="0" MOVE %%D "%p!vidx!%">nul
MOVE "%%D.pdf" "%p!vidx!%"
ECHO %%D File is being procesed now
)
)
I don't know why this code doesn't work, maybe because there is loop inside loop?
Or how to create loop to do the same from 0 to how many lines of variables has been read from input.cdb?
I've tried to run this in separate for loop with temporary variable but it's still not using my string and path variables.
Thank you in advance for any help!
With Regards
Blackfusion
Ugh. More than one problem, and what is the appropriate solution?
First item is a matter of logical design. Let's assume that the batch worked as intended. c!vidx! would be set to %%A and p!vidx! to %%B, so unless there's some unpublished use for c... and p... then you could simply substitute as follows:
setlocal ENABLEDELAYEDEXPANSION
for /F "delims=^ tokens=1,2" %%A in (c:\test\db\input.cdb) do (
FOR /f "tokens=*" %%D IN ('FINDSTR /i /m "%%A" "c:\test\*.txt"') DO (
IF "%ERRORLEVEL%"=="0" MOVE %%D "%%B">nul
MOVE "%%D.pdf" "%%B"
ECHO %%D File is being procesed now
)
)
Now - there's a common fundamental misconception about %var% where var is any variable (including %ERRORLEVEL% and %C!vidx!%...) - a %VAR% occurring in a compound statement (or "block") - within the parentheses if a FOR...DO (in here) or IF...(here) ELSE (or here) is replaced with that variable's value at the time the outermost statement is parsed - before it is executed. If delayedexpansion is invoked (as you have) then !var! refers to the run-time value and %var% to the parse-time value.
Hence, if "%errorlevel%"=="0" would be evaluated according to the state of errorlevel when the for...%%A was parsed, not the value as set by the findstr.
This can be corrected by
setlocal ENABLEDELAYEDEXPANSION
for /F "delims=^ tokens=1,2" %%A in (c:\test\db\input.cdb) do (
FOR /f "tokens=*" %%D IN ('FINDSTR /i /m "%%A" "c:\test\*.txt"') DO (
IF not errorlevel 1 MOVE %%D "%%B">nul
MOVE "%%D.pdf" "%%B"
ECHO %%D File is being procesed now
)
)
Where IF not errorlevel 1 is interpreted as if the CURRENT (run-time) errorlevel is NOT (1 or greater than 1)

incrementing a counter variable inside a FORLOOP

why is the variable "number" not increasing when the FOR loop goes over it again?
setLocal EnableDelayedExpansion
for /f "tokens=* delims= " %%a in (input.txt) do (
set /a N+=1
set /a number=!number!+1
echo %%a !number!.jpg >output.txt
)
OK, try this please:
#echo off &setLocal EnableDelayedExpansion
(for /f "tokens=* delims= " %%a in (input.txt) do (
set /a N+=1
set /a number=!number!+1
echo %%a !number!.jpg
))>output.txt
In case of redirection you need >>output.txt or a code block (parentheses) and >output.txt.
First of all I don't recommend you to enable expansion of variables when you are working with filenames, use it only if you really know what means enabling the delayedexpansion, the benefits (improved velocity) and the negatives (missing characters).
Also you are assigning a value for the variable "N" but you don't use that var.
Here is the code:
#echo off
(for /f "usebackq tokens=* delims= " %%a in ("input.txt") do (
Set /A Number+=1
Call Echo %%a %%number%%.jpg
))>"Output.txt"
Pause&Exit
You should try
setLocal EnableDelayedExpansion
for /f "tokens=* delims= " %%a in (input.txt) do (
set /a N++
set /a number=!number!+1
echo %%a !number!.jpg >output.txt
)
EDIT
Or try:
setLocal EnableDelayedExpansion
for /f "tokens=* delims= " %%a in (input.txt) do (
set /a N++
set /a number=!number!++
echo %%a !number!.jpg >output.txt
)
Or maybe that ++ isnt even supported by what you are using to program this. Let me know though! Shadowpat

How to delete a line of a text file, given the line number using batch (.bat) script?

I want to write a batch script where the user can enter the line number and the script will delete that line of a text file.
Eg: tmp.txt
1. aaa
2. bbb
3. ccc
4. ddd
I want when i execute my script and user inputs 3, the tmp.txt to be
1. aaa
2. bbb
4. ddd
I am trying something like this:
#ECHO OFF
SET /P LINENUMBER=Enter the Line No:
FOR /F "tokens=1* delims=[]" %%a IN ('FIND /n /v "" ^< tmp.txt') DO (
IF %%a equ %LINENUMBER% (
????????????????????
)
)
You cannot modify the file directly. You must create a new file with the desired content and then replace the original file with the new file.
You create the new file by redirecting output and ECHOing the desired content. I use ECHO(%%b in case %%b is empty because the line was blank. ECHO %%b would produce ECHO is off. if b is empty. Most people use ECHO., but that can fail under esoteric conditions. ECHO( will never fail.
You use MOVE to replace the original file with the new.
You can eliminate the need to check for the number within your FOR /F loop by using FINDSTR after FIND to filter out the unwanted line.
Note that your code, as written so far, will strip any leading [ and ] characters from each line. Because the line filter is applied before the FOR iteration, you can improve the situation slightly by setting DELIMS to ] only.
#ECHO OFF
SET /P LINENUMBER=Enter the Line No:
>tmp.txt.new (
FOR /F "tokens=1* delims=]" %%a IN (
'FIND /n /v "" ^<tmp.txt^|FINDSTR /VLB "[%LINENUMBER%]"'
) DO ECHO(%%b
)
>nul MOVE /y tmp.txt.new tmp.txt
If any of your original lines already begin with ] then you can use FINDSTR instead of FIND to introduce the line number. That uses nn: format instead of [nn]. This solution will strip leading : from your lines.
#ECHO OFF
SET /P LINENUMBER=Enter the Line No:
>tmp.txt.new (
FOR /F "tokens=1* delims=:" %%a IN (
'FINDSTR /n "^" tmp.txt^|FINDSTR /VLB "%LINENUMBER%:"'
) DO ECHO(%%b
)
>nul MOVE /y tmp.txt.new tmp.txt
If your text file contains lines that begin both with : and ] then you can't use FOR /F to parse out the line number. Instead you use search and replace. Delayed expansion is toggled on and off within the loop to protect any ! that may exist in the file.
#ECHO OFF
setlocal disableDelayedExpansion
SET /P LINENUMBER=Enter the Line No:
>tmp.txt.new (
FOR /F "delims=" %%a IN (
'FINDSTR /n "^" tmp.txt ^| FINDSTR /VLB "%LINENUMBER%:"'
) DO (
set "ln=%%a"
setlocal enableDelayedExpansion
echo(!ln:*:=!
endlocal
)
)
>nul MOVE /y tmp.txt.new tmp.txt
try out this:
#echo off & setlocal
set "InFile=Z:\Text.txt"
set "OutFile=Z:\Erg.txt"
set /p LineToDelete=
if exist "%OutFile%" del "%OutFile%"
for /f "tokens=1* delims=:" %%i in ('findstr /n $ "%InFile%"^|findstr /b "%LineToDelete%:"') do findstr /v /b /c:"%%j" "%InFile%">>"%OutFile%"

Counting isn't working in batch file

I was trying to count the number of lines in a file using batch file (windows xp sp3).
Here is my code:
#echo off
set line=0
FOR /F "usebackq delims=" %%a in (foo) do (
set /A line+=1
echo line count: %line%
)
echo number of lines: %line%
Although it is counting the lines correctly, but the echo output isn't what I am expecting. I think this has some thing to do with delayed expansion of variable and so I tried SetLocal EnableDelayedExpansion as well, but that's also not working.
here is the output that I am getting:
C:\fiddle\temp>a.bat
line count: 0
line count: 0
line count: 0
line count: 0
line count: 0
number of lines: 5
What's wrong in here?
FYI: I got into this while looking for an answer for THIS question.
Add this line:
SETLOCAL ENABLEDELAYEDEXPANSION
Change this line:
echo line count: %line%
to this:
echo line count: !line!
So, the entire script will look like this:
#echo off
SETLOCAL ENABLEDELAYEDEXPANSION
set line=0
FOR /F "usebackq delims=" %%a in (foo) do (
set /A line+=1
echo line count: !line!
)
echo number of lines: %line%
the batch script I use to count number of lines is the following. call it from the command line with your input file as parameter.
#echo off & setLocal EnableDELAYedeXpansion
for /f "tokens=1 delims=[]" %%a in ('find /v /c "" ^< %1') do (
echo %~n1 %%a
)