I found help on this topic. User: Hackoo had a great piece of code. I ran it on a text file, and it created 5 different variables as expected. It worked perfect. I would like to know how to prompt the user to select which variable they would like to keep. Then take there input and place it into a separate text file. Is that possible? Here is the code which works to obtain the variables.
#echo off
set "File2Read=file.txt"
If Not Exist "%File2Read%" (Goto :Error)
rem This will read a file into an array of variables and populate it
setlocal EnableExtensions EnableDelayedExpansion
for /f "delims=" %%a in ('Type "%File2Read%"') do (
set /a count+=1
set "Line[!count!]=%%a"
)
rem Display array elements
For /L %%i in (1,1,%Count%) do (
echo "Var%%i" is assigned to ==^> "!Line[%%i]!"
)
pause>nul
Exit
::***************************************************
:Error
cls & Color 4C
echo(
echo The file "%File2Read%" dos not exist !
Pause>nul
exit /b
::***************************************************
Related
im currently making something along the lines of a sentence generator, it uses text files which have a list of words in them, for example celebrity.txt has a list of celebrities and this script both shuffles the text file into newcelebrity.txt and takes the first one from that list so its different every time, and ive run into a problem, i want it to be one line and that you can call a variable in the sentance youre typing, not break it down as it is right now, is there a way to have it "this $celebrity is really great" as of now, it works like this: https://gyazo.com/9ae8583ed5457709bd1c1dc9cc0cc106 and outputs as this https://gyazo.com/1a5a90f1fbf80faa73d71791a8c1c761, i dont mind the quotation marks at all, its just the way you input it.
Is there any way to make it work like i want it to or is this a limitation of batch files?
set /p message=Unity:
set /p input=The variable:
set /p after=Unity:
:gen
setlocal
cd ..
cd rcs
echo doing background work, please wait a few seconds :)
for /f "delims=" %%a in (%input%.txt) do call set "$$%%random%%=%%a"
(for /f "tokens=1,* delims==" %%a in ('set $$') do echo(%%b)>new%input%.txt
endlocal
cls
set "File=C:\Users\%USERNAME%\Desktop\gg\rcs\new%input%.txt"
set /a count=0
echo background work done :)
timeout /t 1 >nul
SETLOCAL enabledelayedexpansion
for /F "tokens=* delims=" %%a in ('Type "%File%"') do (
Set /a count+=1
Set "output[!count!]=%%a"
)
For /L %%i in (1,1,%Count%) Do (
Call :Action "!output[%%i]!"
pause
)
Exit
::*******************************************************
:Action
cls
echo.
echo.
echo.
echo.
echo.
echo.
echo.
echo.
echo.
echo %message% %1 %after%
echo.
echo.
echo.
echo.
echo.
echo.
echo.
echo.
echo.
echo if you want to go back and change your inputs type back
echo if you want to continue generating, type gen
echo.
set /p instruction=
goto %instruction%
::*******************************************************
To get rid of the quotation marks, just use %~1 instead of %1.
I'm assuming, you want to input something like 'this $celeb is great' instead of the first three set /p lines (as your output is already in one line).
I used some fixed variables to keep it short - of course you would fetch them from the user and the text file instead, as you already did.
#echo off
setlocal EnableDelayedExpansion
set "count=3"
set "output[3]=John"
set "sentence=this $celeb is great."
REM above would be your 'set /p' instead
call :action "!output[%count%]!"
goto :of
:action
echo !sentence:$celeb=%~1!
(just to be clear: $celeb is not a variable - it's just a string, that we replace later, so from user's perspective, it behaves like a variable)
So, I'm trying to create a custom format image viewer in batch file witch reads from this file named image.ansii2 :
lines=18
line1=[15]---------------
line2=[15]----[160]------[15]-----
line3=[15]---[160]----------[15]--
line4=[15]---[94]---[223]---[0]-[223]-[15]----
line5=[15]--[94]-[223]-[94]-[223]----[0]-[223]---[15]--
line6=[15]--[94]-[223]-[94]--[223]----[0]-[223]---[15]-
line7=[15]--[94]--[223]-----[0]----[15]--
line8=[15]----[223]--------[15]---
line9=[15]---[160]--[26]-[160]--[26]-[160]-[15]-----
line10=[15]--[160]---[26]-[160]--[26]-[160]---[15]---
line11=[15]-[160]----[26]----[160]----[15]--
line12=[15]-[223]--[160]-[26]-[220]-[26]--[220]-[26]-[160]-[223]--[15]--
line13=[15]-[223]---[26]------[223]---[15]--
line14=[15]-[223]--[26]--------[223]--[15]--
line15=[15]---[26]---[15]--[26]---[15]----
line16=[15]--[94]---[15]----[94]---[15]---
line17=[15]-[94]----[15]----[94]----[15]--
line18=[15]---------------
and the program (ansii2.bat) looks like this :
#echo off
for %%a in (%1) do (set ext=%%~xa)
if "%1" == "" (echo No file was specified&pause&exit /b)
if not "%ext%" == ".ansii2" (echo The file specified didn't have the expected extension [%ext%] -^> [.ansii2]&pause&exit /b)
title Ansii2 %1
:0
echo [0m
cls
for /f "delims== tokens=1,2" %%G in (%1) do set "%%G=%%H"
set loop=0
:loop
set /a loop+=1
set line=line%loop%
set "image=echo %!line!:[=[48;5;%"
set "image=%image:]=m%"
set "image=%image:(=[38;5;%"
set "image=%image:)=m%"
set "image=%image:-= %"
%image%
echo %line%
if %loop% == %lines% (goto exitloop)
goto :loop
:exitloop
timeout /t -1 >nul
goto 0
I think that the bug comes from the line 14 but I don't know what to do to fix it...
Could someone help me?
Your attempt at substitution is off, and the method by which you read the file can be improved upon:
All your variables are formatted in the source file, so a for loop can be used to read and assign them by splitting the string at the = delimiter
Delayed expansion is used to perform the substitution, using:
!varname:search=replace! ; where varname is referenced using the meavariable of the for loops first token.
#Echo off & CD "%~dp0"
cls
Setlocal EnableExtensions EnableDelayedExpansion
For /F %%e in ('Echo prompt $E^|cmd')Do Set "\E=%%e"
(For /f "usebackq Tokens=1,2 delims==" %%G in ("%~$Path:1")Do (
Set "%%G=%%H"
Set "%%G=!%%G:[=%\E%[48;5;!"
Set "%%G=!%%G:(=%\E%[38;5;!"
Set "%%G=!%%G:]=m!"
Set "%%G=!%%G:)=m!"
Set "%%G=!%%G:-= !"
If not "%%G" == "lines" <nul set /p "=!%%G!%\E%[0m%\E%[E"
)) > Con
Endlocal
Other notes:
In the event the supplied file cannot be found the following will be output:
The system cannot find the file .
<nul set /p "=!variable!" ; allows safe output of poison characters
%\E%[E ; Equivalent to Outputting a linefeed.
Data structure for your source file:
using single characters for substitution prevents them from being used as characters in the ascii art. use paired characters or unique strings to prevent this. Ie :
\i=%\E%[48;5;
\e=%\E%[38;5;
\m=m
I have the following .txt file:
Marco
Paolo
Antonio
I want to read it line-by-line, and for each line I want to assign a .txt line value to a variable. Supposing my variable is name, the flow is:
Read first line from file
Assign name = "Marco"
Do some tasks with name, let sat set first= %name%
Read second line from file
Assign name = "Paolo"
How do I do it?
This will read a file into an array and assign each line into a variable and display them
#echo off
set "File2Read=file.txt"
If Not Exist "%File2Read%" (Goto :Error)
rem This will read a file into an array of variables and populate it
setlocal EnableExtensions EnableDelayedExpansion
for /f "delims=" %%a in ('Type "%File2Read%"') do (
set /a count+=1
set "Line[!count!]=%%a"
)
rem Display array elements
For /L %%i in (1,1,%Count%) do (
echo "Var%%i" is assigned to ==^> "!Line[%%i]!"
)
pause>nul
Exit
::***************************************************
:Error
cls & Color 4C
echo(
echo The file "%File2Read%" dos not exist !
Pause>nul
exit /b
::***************************************************
I think this answers your question.
#echo off
setlocal EnableExtensions EnableDelayedExpansion
set "somefile=somefile.txt"
if not exist %somefile% (
echo File '%somefile%' does not exist^^!
goto :eof
)
for /f "delims=" %%i in (%somefile%) do (
set "name=%%i"
set "first=!name!"
echo !first!
)
I need to get a batch file running, which helps our employees to change text files without trouble.
As you can see, there are a lot of whit space in this file and they need to be there, otherwise it could not be imported in other programs.
My question: Is it possible to search for a specific column and replace this value with an user input?
I've tried to get something done with help of google and this was the result:
#echo off
for /f "skip=5 delims=" %%a in (Muster.dat) do set "var=%%a"&goto :done
:done
set "R_sph=%var:~126,5%"
echo R_sph: %R_sph%
set /p R_sph_new=Enter new sph:
echo R_sph neu: %R_sph_new%
set "search=R_sph"
set "replace=R_sph_new"
set "textfile=Muster.dat"
set "newfile=Muster2.dat"
(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%
pause
PS: My batch experience is worse and it would be great to explain every step in the code you send me.
Edit: We generate a lot of files like this every day and only some of them need so be edited. The construction of this files is always the same but with other values so it's important so search via column.
Change the main loop in your batch file so that:
it only changes the 6th line;
it only changes the 5 characters from position 126 to 130.
And just to make the batch script more robust, you can also validate user input to ensure that they've entered exactly 5 characters as the replacement string.
Here's the whole file with suggested changes:
#echo off
setlocal enabledelayedexpansion
for /f "skip=5 delims=" %%a in (Muster.dat) do set "var=%%a"&goto :done
:done
set "R_sph=%var:~126,5%"
echo R_sph: %R_sph%
set /p R_sph_new=Enter new sph:
echo R_sph neu: %R_sph_new%
rem Validate user input - ensure it's exactly 5 characters
set "replace=%R_sph_new% "
set "replace=%replace:~0,5%"
if not "%R_sph_new%" == "%replace%" (
echo Don't be silly.
exit /b 1
)
set "textfile=Muster.dat"
set "newfile=Muster2.dat"
set /a lineNumber = 0
(for /f "delims=" %%i in (%textfile%) do (
set /a lineNumber += 1
set "line=%%i"
if !lineNumber! == 6 set "line=!line:~0,126!%replace%!line:~131!"
echo(!line!
))>"%newfile%"
rem It might be safer to rename %textfile% to %textfile%.BAK instead of deleting it.
del %textfile%
rename %newfile% %textfile%
endlocal
pause
set "search=R_sph"
set "replace=R_sph_new"
should
set "search=%R_sph%"
set "replace=%R_sph_new%"
that is, set the values of search and replace to the contents of the variables. Your code sets search to the string R_sph.
? Are you sure that the value in R_sph will be unique in your file?
Thank you very much Klitos Kyriacou, that's exactly what I was looking for!
But unfortunately this batch does not change anything in this text file, the whole code looks like this:
#echo off
:R_sph
for /f "skip=5 delims=" %%a in (Muster.dat) do set "var=%%a"&goto :done
:done
set "R_sph=%var:~49,5%"
echo R_sph: %R_sph%
set /p R_sph_new=Enter new sph:
set "replace=%R_sph_new%"
set "textfile=Muster.dat"
set "newfile=Muster2.dat"
setlocal enabledelayedexpansion
set /a lineNumber = 0
(for /f "delims=" %%i in (%textfile%) do (
set /a lineNumber += 1
set "line=%%i"
if !lineNumber! == 6 set "line=!line:~0,49!%replace%!line:~54!"
echo(!line!
))>"%newfile%"
endlocal
:replace file
del %textfile%
rename %newfile% %textfile%
pause
Edit: I was in hurry and dind't get how to set it up. Now I changed the code and it's working!
I'm 90% of the way there on a Windows Batch file.
It takes 2 input parameters, input and output files.
It then reads in the input file, and substrings certain lines into arrays (Well line 2 onwards).
Then we come to a loop for outputting.
With delayed expansion on my counter for going through the array doesn't update unless I use !counter2!, %counter2% doesn't work.
Using !arrayname[!counter2!]! doesn't work.
Here is the code as it stands.
#Echo off
if [%1] == [] goto usage
if [%2] == [] goto usage
echo start time : %time%>logfile.log
set input_file=%1
set output_file=%2
if exist %output_file% del %output_file%
Echo Start reading %input_file%>> logfile.log
setLocal EnableDelayedExpansion
set /a counter=1
for /F "tokens=* delims=" %%a in ('type %input_file%') DO (
::echo !counter!
if "!counter!"=="1" set header=%%a
if not "!counter!"=="1" (
set data[!counter!]=%%a
set line=%%a
set jobnumber[!counter!]=!line:~0,7!
set docnumber[!counter!]=!line:~7,5!
set pagecount[!counter!]=!line:~12,2!
set customernumber[!counter!]=!line:~14,20!
set presort[!counter!]=0000
set postcode[!counter!]=0000
set inserts[!counter!]=!line:~36,11!
set filler[!counter!]=000000
set address[!counter!]=!line:~58,350!
set filler2[!counter!]=" "
set endline[!counter!]=X
)
set /a counter=counter+1
)
Echo Start writing %output_file%>> logfile.log
for /L %%G in (2,1,%counter%) DO (
set counter2=%%G
echo !counter2!
echo !jobnumber[%counter2%]!!docnumber[%counter2%]!!pagecount[%counter2%]!!customernumber[%counter2%]!!presort[%counter2%]!!postcode[%counter2%]!!inserts[%counter2%]!!filler[%counter2%]!!address[%counter2%]!!filler2[%counter2%]!!endline[%counter2%]!>>%output_file%
)
echo end time : %time%>>logfile.log
pause
goto :eof
:usage
echo Usage: blah.bat input_filename output_filename
pause
goto :eof
It is the echo !jobnumber[%counter2%]! where things are not being resolved.
The echo !counter2! works fine.
Before you ask, Yes I know this could be done better and easier in C# or another programming language, However I am tasked with doing it in a windows batch file.
Thanks in advance for any help provided.
Tel
Try with:
for /L %%G in (2,1,%counter%) DO (
set counter2=%%G
echo !counter2!
echo !jobnumber[%%G]!!docnumber[%%G]!!pagecount[%%G]!!customernumber[%%G]!!presort[%%G]!!postcode[%%G]!!inserts[%%G]!!filler[%%G]!!address[%%G]!!filler2[%%G]!!endline[%%G]!>>%output_file%
)
You are not changing the value of the coutner2 so you don't need it and you can directly use %%G.
Though if you need changes in counter2 you'll have to wrap it again in for loop and to use its tokens.