Outputting string to a text file from a batch program [duplicate] - string

I have a file report.txt having comma separated values like (1,2,3,4). I am checking if the file is not blank then assign the 4 variables with values in the file. But the variables are not set. Any help why this is happening?
setlocal enabledelayedexpansion
for /f %%i in ("Report.txt") do set size=%%~zi
if %size% gtr 0 (
for /F "tokens=1-4 delims=," %%A in ("Report.txt") do (
set "var1=%%a"
set "var2=%%b"
set "var3=%%c"
set "var4=%%d"
)
set var
)
echo %var1%

You've enabled delayed expansion, but you aren't using it. In order to use delayed expansion, you need to use !variable! instead of %variable%. Additionally, the variable specified in for loops is case-sensitive, so you either need to set var1 equal to %%A or use %%a as the loop variable.
setlocal enabledelayedexpansion
for /f %%i in ("Report.txt") do set size=%%~zi
if %size% gtr 0 (
for /F "tokens=1-4 delims=," %%a in (Report.txt) do (
set "var1=%%a"
set "var2=%%b"
set "var3=%%c"
set "var4=%%d"
)
set var
)
echo !var1!

setlocal enabledelayedexpansion
for /f %%i in ("Report.txt") do set size=%%~zi
if %size% gtr 0 (
I changed the code as below and it started working. Thank you guys for your time. Appeciate it.
for /F "tokens=1-4 delims=," %%A in (%cd%\Report.txt) do (
set "var1=%%A"
set "var2=%%B"
set "var3=%%C"
set "var4=%%D"
)
set var
)
echo !var1!

Related

Sort floating-point numbers in batch

Hello StackExchange community!
I am trying to solve the problem of sorting floating-point values with batch.
To the point. I have a log file (INPUT.txt) in the following form:
889.W_1.153,46
889.W_1.37,43
889.W_1.28,81
889.W_1.34,70
155.W_2.22,67
155.W_2.108,06
155.W_2.22,11
155 W_2 22,65
I want to sort this by 1st and 3rd column. I want output (OUTPUT.txt) in this form:
155.W_2.22,11
155.W_2.22,65
155.W_2.22,67
155.W_2.108,06
889.W_1.28,81
889.W_1.34,70
889.W_1.37,43
889.W_1.153,46
I wrote a small script and it works almost good because my result is:
155 108,06 W_2
155 22,11 W_2
155 22,65 W_2
155 22,67 W_2
889 153,46 W_1
889 28,81 W_1
889 34,70 W_1
889 37,43 W_1
Dots and column order are not so important, actual problem is with numbers longer than 2 digits. A comma is treated as a " higher " than the number . Below is the script :
#echo off
setlocal enabledelayedexpansion
for /F "tokens=1-3 delims=." %%a in (INPUT.txt) do set "a[%%a %%c ]=%%b"
for /F "tokens=2-4 delims=[.]=" %%a in ('set a[') do echo %%a%%c%%b>> OUTPUT.txt
Correct sorting is not everything I need. I would also have the ability (later in the script) to delete a whole row in which the number is longer than 2 digits in this case it will be row with 153,49 and 108,06. Any help would be very valuable to me .
Numeric sorting is not supported by pure batch programs and need to be worked around. The best method is to pad numbers with zeros and do native alphabetic sorting then.
To actually sort, you can use set as you already did in your script. Here is a batch file which features the said zero-padding:
#echo off
setlocal EnableExtensions DisableDelayedExpansion
rem // Define constants here:
set "FILE=%~1" & rem // (1st command line argument: file to process)
set "RTNF=%~2" & rem // (2nd command line argument: file to store result)
set /A DIGS=4 & rem // (total number of digits for zero-padding)
set /A DLIM=2 & rem // (maximum number of digits for 3rd field in file)
if not defined RTNF set "RTNF=con"
for /F "eol== delims==" %%V in ('2^> nul set ARRAY[') do set "%%V="
setlocal EnableDelayedExpansion
set "PAD=" & for /L %%D in (1,1,%DIGS%) do set "PAD=!PAD!0"
endlocal & set "PAD=%PAD%"
setlocal EnableDelayedExpansion
for /F usebackq^ delims^=^ eol^= %%L in ("!FILE!") do (
endlocal
for /F "eol=. tokens=1,3,4 delims=., " %%A in ("%%L") do (
set "FIELD1=%PAD%%%A"
set "FIELD3=%%B"
set "FIELD4=%%C%PAD%"
setlocal EnableDelayedExpansion
if "!FIELD3:~%DLIM%!"=="" (
set "FIELD3=%PAD%!FIELD3!"
for /F delims^=^ eol^= %%T in ("!FIELD1:~-%DIGS%!.!FIELD3:~-%DIGS%!,!FIELD4:~,4!") do (
endlocal
set "ARRAY[%%T]=%%L"
)
) else (
endlocal
)
)
setlocal EnableDelayedExpansion
)
> "!RTNF!" (
for /F "tokens=2 delims== eol==" %%I in ('set ARRAY[') do (
endlocal
echo(%%I
setlocal EnableDelayedExpansion
)
)
endlocal
endlocal
exit /B
For sorting, a pseudo-array variable ARRAY is used, whose indexes contain the zero-padded numbers of the applicable fields for sorting, the values are the original lines of the input file:
ARRAY[0155.0022,1100]=155.W_2.22,11
ARRAY[0155.0022,6500]=155 W_2 22,65
ARRAY[0155.0022,6700]=155.W_2.22,67
ARRAY[0889.0028,8100]=889.W_1.28,81
ARRAY[0889.0034,7000]=889.W_1.34,70
ARRAY[0889.0037,4300]=889.W_1.37,43
Here is another approach using a temporary file and the sort command to do the sorting. This is more generic as it does not fail on special characters, like = for instance, which adversely impacts the method based on the set command. This is the code:
#echo off
setlocal EnableExtensions DisableDelayedExpansion
rem // Define constants here:
set "FILE=%~1" & rem // (1st command line argument: file to process)
set "RTNF=%~2" & rem // (2nd command line argument: file to store result)
set /A DIGS=4 & rem // (total number of digits for zero-padding)
set /A DLIM=2 & rem // (maximum number of digits for 3rd field in file)
set "TMPF=%TEMP%\%~n0_%RANDOM%.tmp"
if not defined RTNF set "RTNF=con"
setlocal EnableDelayedExpansion
set "PAD=" & for /L %%D in (1,1,%DIGS%) do set "PAD=!PAD!0"
endlocal & set "PAD=%PAD%"
setlocal EnableDelayedExpansion
> "!TMPF!" (
for /F usebackq^ delims^=^ eol^= %%L in ("!FILE!") do (
endlocal
set "LINE=%%L"
for /F "eol=. tokens=1,3,4 delims=., " %%A in ("%%L") do (
set "FIELD1=%PAD%%%A"
set "FIELD3=%%B"
set "FIELD4=%%C%PAD%"
setlocal EnableDelayedExpansion
if "!FIELD3:~%DLIM%!"=="" (
set "FIELD3=%PAD%!FIELD3!"
echo(!FIELD1:~-%DIGS%!.!FIELD3:~-%DIGS%!,!FIELD4:~,4!^|!LINE!
)
endlocal
)
setlocal EnableDelayedExpansion
)
)
> "!RTNF!" (
for /F delims^=^ eol^= %%I in ('sort "!TMPF!"') do (
endlocal
set "LINE=%%I"
setlocal EnableDelayedExpansion
echo(!LINE:*^|=!
)
)
del "!TMPF!"
endlocal
endlocal
exit /B
The temporary file used for sorting contains the zero-padded numbers of the applicable fields for sorting, a predefined separator | and the original lines of the input file:
0889.0037,4300|889.W_1.37,43
0889.0028,8100|889.W_1.28,81
0889.0034,7000|889.W_1.34,70
0155.0022,6700|155.W_2.22,67
0155.0022,1100|155.W_2.22,11
0155.0022,6500|155 W_2 22,65
Your code just required a small adjustment:
#echo off
setlocal EnableDelayedExpansion
for /F "tokens=1-4 delims=.," %%a in (INPUT.txt) do (
set /A "first=1000+%%a,third=100000+%%c%%d"
set "a[!first!!third!]=%%a.%%b.%%c,%%d"
)
(for /F "tokens=2 delims==" %%a in ('set a[') do echo %%a) > OUTPUT.txt

Assign Last Two Lines of Text as Variable via Batch Script

Hi I have a text file in which I need to use the last two lines as two variables in a batch script. Example:
file.txt contains:
Release2010
Release2011
Release2013
I need var1 = Release2011 and var2 = Release2013. The length of the file will vary but I will always need the last two lines.
Thanks for your assistance!
you might try this:
#ECHO OFF &SETLOCAL ENABLEDELAYEDEXPANSION
FOR /f "delims=" %%a IN (file) DO (
SET "var2=!var1!"
SET "var1=%%a"
)
ECHO(var1: %var1%
ECHO(var2: %var2%
and the same without delayed expansion:
#ECHO OFF &SETLOCAL
FOR /f "delims=" %%a IN (file) DO (
CALL SET "var2=%%var1%%"
SET "var1=%%a"
)
ECHO(var1: %var1%
ECHO(var2: %var2%
Here's one way to do it without enabling delayed expansion.
#ECHO OFF
FOR /F %%A IN (InFile.txt) DO (
CALL :SetSecondLastLine
SET LastLine=%%A
)
ECHO.SecondLastLine=%SecondLastLine%
ECHO.LastLine=%LastLine%
pause
GOTO :eof
:SetSecondLastLine
SET SecondLastLine=%LastLine%
GOTO:EOF

character manipulation in file cmd

this is file.txt
hello
hai
So i wanna create a program that will read this file. and then replace every ALPHABET with the succeeding one. keeping all numbers and other symbols intact.
so the file.txt would become
ifmmp
ibj
current have tried reading every \n and then reading every character in the line, but echoing them would result in it being in different lines
ie
for /f "delims=" %%i in ('^<%path% findstr /n "^"') do (
set "line=%%i"
setlocal enabledelayedexpansion
set "line=!line:*:=!"
set "num=-1"
:loop
set /a num=num+1
call set "name2=%%line:~%num%,1%%"
if defined name2 (
rem set /a name2+=1 this statement wont work
echo %name2%
goto :loop )
)
but then the output i get is
echo is off
e
l
l
o
any ideas?
The set /a command does only work with numbers, you can try this:
#echo off&setlocal
set "alfa=abcdefghijklmnopqrstuvwxyza"
set "test=hello hai"
set /a num=0
:loop
call set "char=%%test:~%num%,1%%"
if not defined char goto:eof
call set "alf1=%%alfa:*%char%=%%"
if "%char%" neq " " echo %alf1:~0,1%
set /a num+=1
goto:loop
..output is:
i
f
m
m
p
i
b
j
Here is a ROT13 batch file - what you are describing is a ROT1 translation. Maybe this will work for you as it is, or give you ideas and you can modify it.
#echo off
:: by aacini
:: program works as a filter, that is, it read lines from keyboard (stdin) and send output to screen (stdout). "type filetext.txt|rot13.bat" or "rot13.bat < filetext.txt"
:: with d benham update
#echo off
:: simple rot-13 conversion filter program
setlocal disableDelayedExpansion
set lower=abcdefghijklmnopqrstuvwxyz
set upper=ABCDEFGHIJKLMNOPQRSTUVWXYZ
for /l %%a in (0,1,25) do (
set /a "rot13=(%%a+13)%%26"
setlocal enableDelayedExpansion
for %%b in (!rot13!) do for /f "tokens=1-4" %%A in (
"!lower:~%%a,1! !lower:~%%b,1! !upper:~%%a,1! !upper:~%%b,1!"
) do (
endlocal
set "lower%%A=%%B"
set "upper%%C=%%D"
)
)
for /f "delims=" %%a in ('findstr /n "^"') do (
set "line=%%a"
setlocal enableDelayedExpansion
set "line=!line:*:=!"
set output=
if defined line (
set /a len=0
for /l %%b in (12,-1,0) do (
set /a "len|=1<<%%b"
for %%c in (!len!) do if "!line:~%%c,1!" equ "" set /a "len&=~1<<%%b"
)
for /l %%b in (0,1,!len!) do (
set "char=!line:~%%b,1!"
if defined lower!char! for /f delims^=^ eol^= %%c in ("!char!") do (
if "!lower:%%c=%%c!" neq "!lower!" (
set "char=!upper%%c!"
) else set "char=!lower%%c!"
)
set "output=!output!!char!"
)
)
echo(!output!
endlocal
)

A Batch file to read a file and replace a string with a new one

I want to create a batch file to read every line of a file in a loop and replace a string with another one. Following is my code snippet:
for /F "tokens=*" %%i in (myfile) do (
set str=%%i
set str=%str: %oldstring% = %newstring%%
echo %str% >> newfile
)
This results in a newfile with 'Echo is off' as many lines as there are in myfile. Seems like str variable holds no value at all when assigned to %%i. Can someone help me?
Try out this small script:
#echo off
set val=50
echo %val%
for /l %%i in (1,1,1) do (
set val=%%i
echo %val%
)
echo %val%
pause>nul
The output is:
50
50
1
Not what you expected, right?
That's because in a for loop, variables aren't updated until the loop has finished. To combat this, you can use setlocal enabledelayedexpansion, and replace the percent signs (%) with an exclamation mark (!):
#echo off
setlocal enabledelayedexpansion
set val=50
echo %val%
for /l %%i in (1,1,1,) do (
set val=%%i
echo !val!
)
echo %val%
pause>nul
The output:
50
1
1
The reason the str variable holds no value (during the for loop) is because it hasn't been set beforehand.
So, with these quick modifications, your script will work...
setlocal enabledelayedexpansion
for /f "tokens=*" %%i in (myfile) do (
set str=%%i
set str=!str: %oldstring% = %newstring%!
echo !str! >> newfile
)
By the way, this snippet is assuming that oldstring and newstring won't be set within the forloop, otherwise things will get messy.
Have fun.
having spent some time at this I got the correct way:
#echo off
setlocal enabledelayedexpansion
set oldstring=AF-07295
set /a count=1000
for %%f in (*.*) do (
set /a count=!count!+1
for /f "tokens=*" %%i in (%%f) do (
set str=%%i
call set str=%%str:!oldstring!=!count!%%
echo !str! >> %%~nf.ordnew
)
)
endlocal
setlocal ENABLEDELAYEDEXPANSION
set filein="c:\program files\test1.txt"
set fileout="c:\program files\test2.txt"
set old=#VERSION#
set new=2.0.3
for /f "tokens=* delims=ΒΆ" %%i in ( '"type %filein%"') do (
set str=%%i
set str=!str:%old%=%new%!
echo !str! >> %fileout%
)
working perfect
and isn't removing white spaces at the begining of the lines file

Using DOS batch script: find a line in a properties file and replace text

Trying to replace a string in a properties file on a certain line by using a batch file. I know that this can be done WITHOUT the use of a temp file, as I have seen it before, but forgotten how to do it.
I know that if I have a var.properties file that contains this:
CLASSPATH=bsh.jar;other.jar
VARTEST=dummy
ANOTHERVAR=default
I am trying to update the CLASSPATH value in the .properties file without changing the order of the properties file.
This is a properties file and so I believe the answer would be related to using:
for /f "tokens=1,2* delims==" %%i in (var.properties) do (
#echo Key=%%i Val=%%j
)
Instead of findstr use find with the /v and /i switches on "classpath". This will OMIT returning the line with classpath in it, then you can echo what you want in the file along w/VARTEST=dummy
SET NEWVAL=CLASSPATH=test.jar
SET FILE=think.properties
FOR /F "USEBACKQ tokens=*" %%A IN (`TYPE "%FILE%" ^|FIND /V /I "classpath"`) DO (
ECHO CLASSPATH=%NEWVAL%>>"%FILE%"
ECHO %%A>>"%FILE%"
)
EDIT:
SETLOCAL ENABLEDELAYEDEXPANSION
SET NEWVAL=test.jar
SET OLDFILE=OLD_think.properties
SET NEWFILE=think.properties
SET COUNT=1
MOVE "%NEWFILE%" "%OLDFILE%"
FOR /F "USEBACKQ tokens=*" %%A IN (`TYPE "%OLDFILE%" ^|FIND /C /I "classpath"`) DO (
SET LINE=%%A
)
FOR /F "USEBACKQ tokens=*" %%A IN (`FIND /V "" ^<"%OLDFILE%"`) DO (
IF %COUNT% NEQ %LINE% (ECHO %%A>>"%NEWFILE%") ELSE (ECHO %NEWVAL%>>"%NEWFILE%")
SET /a COUNT=!COUNT!+1
)
Basically states,
rename think.properties to OLD_think.properties
read OLD_think.properties and find the line number with string
"classpath" in it and set it to variable LINE
Find all lines in OLD_think.properties, and echo them into think.properties. once you reach the line where your "CLASSPATH" string existed, it inserts the new line you wanted to replace it with, and everything else stays the same.
I finally broke down and accepted a method using a "temp" file. Using delayed expansion with the '!' character solved my question. Much of this success was due to input by mecaflash .
You can call this script with: CALL Script.bat PropKey NewPropValue Filename
#echo off
:: script for updating property files
SETLOCAL EnableExtensions
SETLOCAL EnableDelayedExpansion
if "%3"=="" (
ECHO Script will optionally accept 3 args: PropKey PropVal File
SET PROPKEY=UseCompression
SET PROPVAL=false
SET FILE=config.properties
) ELSE (
SET PROPKEY=%1
SET PROPVAL=%2
SET FILE=%3
)
FINDSTR /B %PROPKEY% %FILE% >nul
IF %ERRORLEVEL% EQU 1 GOTO nowork
MOVE /Y "%FILE%" "%FILE%.bak"
FOR /F "USEBACKQ tokens=*" %%A IN (`TYPE "%FILE%.bak" ^|FIND /N /I "%PROPKEY%"`) DO (
SET LINE=%%A
)
FOR /F "tokens=1,2* delims=]" %%S in ("%LINE%") DO SET LINE=%%S
SET /A LINE=%LINE:~1,6%
SET /A COUNT=1
FOR /F "USEBACKQ tokens=*" %%A IN (`FIND /V "" ^<"%FILE%.bak"`) DO (
IF "!COUNT!" NEQ "%LINE%" (
ECHO %%A>>"%FILE%"
) ELSE (
ECHO %PROPKEY%=%PROPVAL%>>"%FILE%"
ECHO Updated %FILE% with value %PROPKEY%=%PROPVAL%
)
SET /A COUNT+=1
)
GOTO end
:nowork
echo Didn't find matching string %PROPKEY% in %FILE%. No work to do.
pause
:end

Resources