count the number of certain characters - batch-file

I would like to write a batch file to count the number of symbols "(" and ")" in file.txt
For example, I have file with this string:
"(((
( ((
( ("
Answer would be 8.
But I have code and my answer is 3 :
#echo off
set "f=file.txt"
set "sk9=("
set "sk0=)"
set /a "k9=0"
set /a "k0=0"
for /f "usebackq delims=" %%a in ("%f%") do for %%i in (%%a) do (
if "%%i"=="%sk9%" (
set /a k9=k9+1
) )
echo %k9%

Windows command processor cmd.exe executing batch files line by line is definitely not the right application for this task. It is designed to execute commands and applications. However, here is a batch file counting parentheses/round brackets in a text file.
#echo off
setlocal EnableExtensions DisableDelayedExpansion
set "OpenBracketCount=0"
set "CloseBracketCount=0"
for /F "usebackq tokens=* eol=" %%I in ("File.txt") do (
set "TextLine=%%I"
call :ProcessLine
)
echo Number of opening brackets: %OpenBracketCount%
echo Number of closing brackets: %CloseBracketCount%
endlocal
goto :EOF
:ProcessLine
set "TextLine=%TextLine:"=%"
if not defined TextLine goto :EOF
set "TempLine=%TextLine:(=%"
if not defined TempLine goto BracketCount
set "TempLine=%TempLine:)=%"
if "%TempLine%" == "%TextLine%" goto :EOF
:BracketCount
if "%TextLine:~0,1%" == "(" ( set /A "OpenBracketCount+=1" ) else if "%TextLine:~0,1%" == ")" set /A CloseBracketCount+=1
set "TextLine=%TextLine:~1%"
if defined TextLine goto BracketCount
goto :EOF
Command FOR with using option /F to process lines from a text file ignores by default empty lines and lines starting with a semicolon which is the default for end of line option eol, and splits up the line into substrings (tokens) on spaces tabs. It is okay to ignore empty lines, but lines with a ; at beginning should not be ignored for counting parentheses.
Both unwanted line processing behaviors could be disabled with using usebackq^ delims^=^ eol^= to get the entire line assigned to the environment variable TextLine by specifying no delimiters and no end of line character. It is not possible to enclose this option string in double quotes in this special case which requires to escape the spaces and equal signs interpreted by default as argument string separators by caret character ^ to interpret them as literal characters.
But better is to use double quoted option string "usebackq tokens=* eol=" which defines also no end of line character, but keeps space and horizontal tab as delimiters. So assigned to loop variable I is the line after removing leading spaces/tabs. That is good here as it avoids processing lines containing only spaces/tabs and can reduce also the number of characters to process in the subroutine.
In the subroutine ProcessLine first all double quotes are removed from the line read from text file as a " could later in remaining command lines result in a syntax error on execution. It is of course possible that a line contains only one or more " resulting in environment variable TextLine is not defined anymore after removing all double quotes in which case the line definitely does not contain parentheses to count.
Next is assigned to environment variable TempLine the line read from text file (without leading spaces/tabs and without all double quotes) with all ( and ) removed from the line. The line does not contain a parenthesis if TempLine is equal TextLine and so the subroutine can be exited immediately to reduce the execution time of the batch file.
Otherwise the current line contains at least one round bracket and so it is necessary to compare each character of the remaining line with ( and ) to count them .
For understanding the used commands and how they work, open a command prompt window, execute there the following commands, and read entirely all help pages displayed for each command very carefully.
call /?
echo /?
endlocal /?
for /?
goto /?
if /?
set /?
setlocal /?
See also Where does GOTO :EOF return to?

This solution is based on an efficient subroutine that you may use to count any character you wish:
#echo off
setlocal
call :CountChar "(" test.txt LeftParen=
echo Number of left parens = %LeftParen%
goto :EOF
:CountChar char file result=
setlocal DisableDelayedExpansion
rem Create a copy of input file with the desired characters removed
rem Process all file lines in %%a FOR replaceable parameter
(for /F "usebackq delims=" %%a in ("%~2") do (
set "line=%%a"
rem Enable status to expand line variable
setlocal EnableDelayedExpansion
rem Output the variable without the desired character
echo(!line:%~1=!
endlocal
rem Store previous smaller output in another file
)) > smallerFile.txt
rem Get the size difference between both files
for %%a in ("%~2") do for %%b in (smallerFile.txt) do (
rem Store the result in third subroutine parameter
endlocal & set /A "%~3=%%~Za-%%~Zb"
)
del smallerFile.txt
exit /b

Related

Batch Script not displaying entire output

I have an input text file with some server names
I am trying to replace the 'new line' for each server with |.
abcdef.abcdef.abcdef
testing
example
When executed in cmd.exe my script doesn't parse all lines from the input file. Say, if I have 1000 servers in my input file, I can see the output in the Command Prompt window for just around 500 servers.
#echo off
setlocal enableextensions
SETLOCAL EnableDelayedExpansion
rem Purpose - To remove domain name of servers and convert line by line strings to | seperated strings.
type nul > Del_Output.txt
for /f "tokens=1 delims=." %%a in (Downtime.txt) do (
echo(%%a>> Del_Output.txt
)
type Del_Output.txt
rem Initialize the output line
set "line="
rem Catenate all file lines in the same variable separated by "|"
for /F "delims=" %%a in (Del_Output.txt) do set "line=!line!|%%a"
rem Show final line, removing the leading "|"
rem echo !line:~1!>FinalOutput.txt
echo !line:~1!
rem type "C:\Users\AAithal\Desktop\MoogSoft_Downtime\FinalOutput.txt"
ENDLOCAL
Some pointers on the issue would be very helpful.
This should work:
#echo off
setlocal
set "first="
< nul (
for /F "delims=." %%a in (Downtime.txt) do (
if not defined first (
set "first=1"
set /P "=%%a"
) else (
set /P "=|%%a"
)
)
echo/
) > Output.txt
As others have indicated already, the maximum length of a batch variable is 8192 characters, so all names that exceed such a size are not included in your code...
The solution is not use a variable to collect the output. The set /P command allows to output a string with no LF at end, so the input lines are just joined in a long output line.
#ECHO OFF
SETLOCAL ENABLEDELAYEDEXPANSION
SET "sourcedir=U:\sourcedir"
SET "filename1=%sourcedir%\q56905805.txt"
SET "outline="
FOR /f "usebackqdelims=" %%a IN ("%filename1%") DO (
FOR /f "tokens=1*delims=." %%i IN ("%%a") DO IF "%%j"=="" (
SET "outline=!outline!|%%a"
) ELSE (
IF DEFINED outline ECHO !outline!
SET "outline=%%i"
)
)
IF DEFINED outline ECHO !outline!
GOTO :EOF
You would need to change the setting of sourcedir to suit your circumstances. The listing uses a setting that suits my system.
I used a file named q56905805.txt containing your data for my testing.
The usebackq option is only required because I chose to add quotes around the source filename.
Assign each line to %%a, then reparse it with the delimiter. It it contains the delimiter, it's a new server, so output the previous one and start anew, else accumulate with the required separator.

How to split filename by delimiter " - " and echoing the part before and after?

I need help to split a file name or folder name into two parts.
All files in the subfolders use always the same naming convention:
mainfolder/artist - title/artist - title.ext
I started with creating a batch file which writes .nfo files (recursive) for video files. Everything is working fine, but I just can't find a way to echoing the part1 (artist) before delimiter  -  and after it to have part2 (title).
Here is what I have now:
#echo off
TITLE NFO creator Musicvideos
COLOR B
ECHO -------------------------------------------------------------------------
ECHO Create NFO for Musicvideos, all existing will be overwritten
ECHO Push key to Start
ECHO -------------------------------------------------------------------------
ECHO.
PAUSE > NUL
REM Ende Header
for /r %%a in (*.mkv *.avi *.mp4) do (
(
echo ^<?xml version="1.0" encoding="UTF-8" standalone="yes"?^>
echo ^<musicvideo^>
for %%b in ("%%~na") do echo ^ ^<title^>%%~b^</title^>
echo ^ ^<^!-- start test set attributes --^>
for %%b in ("%%~na") do echo ^ ^<path^>%~dp0^</path^>
for %%b in ("%%~na") do echo ^ ^<name^>%%~na^</name^>
for %%b in ("%%~na") do echo ^ ^<filenameandpath^>%%~a^</filenameandpath^>
for %%b in ("%%~na") do echo ^ ^<basepath^>%%~a^</basepath^>
for %%b in ("%%~na") do echo ^ ^<before^>^</before^>
REM for "tokens=1,2 delims= - " %%b in ("%%~na") do (
REM echo ^ ^<before^>^%%a</before^>
REM echo ^ ^<after^>^%%b</after^>
REM )
REM test end
echo ^ ^<rating^>^0.000000^</rating^>
echo ^ ^<userrating^>^8^</userrating^>
echo ^ ^<epbookmark^>^0.000000^</epbookmark^>
echo ^ ^<year^>^</year^>
echo ^ ^<track^>^-1^</track^>
echo ^ ^<album^>^</album^>
echo ^ ^<artist^>^</artist^>
echo ^ ^<genre^>^</genre^>
echo ^ ^<outline^>^</outline^>
echo ^ ^<plot^>^</plot^>
echo ^ ^<tagline^>^</tagline^>
echo ^ ^<thumb^>^</thumb^>
echo ^ ^<status^>^</status^>
echo ^ ^<studio^>^</studio^>
echo ^ ^<art^>
echo ^ ^<fanart^>%~dp0^%%~na^-fanart.jpg^</fanart^>
echo ^ ^<poster^>%~dp0^%%~na^-poster.jpg^</poster^>
echo ^ ^<artistthumb^>%~dp0^%%~na^-artistthumb.jpg^</artistthumb^>
echo ^ ^<banner^>%~dp0^%%~na^-banner.jpg^</banner^>
echo ^ ^<clearlogo^>%~dp0^%%~na^-clearlogo.png^</clearlogo^>
echo ^ ^<discart^>%~dp0^%%~na^-discart.png^</discart^>
echo ^ ^<landscape^>%~dp0^%%~na^-landscape.jpg^</landscape^>
echo ^ ^</art^>
echo ^</musicvideo^>
)>"%%~dpna.nfo"
)
ECHO.
ECHO Creatin is done
ECHO Push key to exit
ECHO.
PAUSE > NUL
This is the way I would do it:
#echo off
setlocal
for /R %%A in (*.mkv *.avi *.mp4) do call :SplitFileName "%%~nA"
goto :EOF
:SplitFileName
set "FileName=%~1"
set "Title=%FileName: - =" & set "Artist=%"
echo Artist=%Artist%
echo Title=%Title%
exit /B
Further details at Split string with string as delimiter. Pay attention to the comment at such an answer...
I cannot find a reason for all the loops for %%b in ("%%~na") do you are using, particularly because you are often not even using %%b in their bodies.
Anyway, splitting file names at a certain sub-string can be easily done by first replacing the sub-string by a single character that is forbidden in file names (like :, for example) and then using that character as a delimiter in a for /F loop:
#echo off
setlocal EnableExtensions DisableDelayedExpansion
rem // Loop through all matching files recursively:
for /R %%a in (*.mkv *.avi *.mp4) do (
rem // Store file name in variable:
set "NAME=%%~na"
rem /* Toggle delayed expansion to be able to write a variable
rem in the same block of code without losing `!`: */
setlocal EnableDelayedExpansion
rem // Remove everything before first occurrence of and including ` - `:
echo Title: !NAME:* - =!
rem // Replace ` - ` by `:` and use the latter as delimiter:
for /F "tokens=1 delims=: eol=:" %%b in ("!NAME: - =:!") do (
endlocal
echo Artist: %%b
)
)
endlocal
exit /B
The above code assumes that both the artist and the title portions are not empty. The title part may include the sub-string - on its own.
This is an example on how to split a file name on first hyphen character.
#echo off
setlocal EnableExtensions DisableDelayedExpansion
for /R %%A in (*.mkv *.avi *.mp4) do (
for /F "eol=| tokens=1* delims=-" %%B in ("%%~nA") do (
set "Artist=%%B"
set "Title=%%C"
setlocal EnableDelayedExpansion
if "!Artist:~-1!" == " " set "Artist=!Artist:~0,-1!"
if defined Title if "!Title:~0,1!" == " " set "Title=!Title:~1!"
echo Artist=!Artist!
if defined Title (echo Title=!Title!) else echo %%~na has no title.
endlocal
)
)
endlocal
The outer FOR loop searches recursive in current directory and all subdirectories for non-hidden files with file extension mkv, avi or mp4 and assigns the full qualified file name (file path + file name + file extension) of a found file to loop variable A.
The inner FOR loop interprets just the file name without path and file extension as string to process.
The end of line character is redefined from default ; which can be at beginning of a file name to | which no file name can ever contain to avoid that a file name starting by chance with a semicolon is ignored by the inner FOR loop.
By default FOR with option /F processing a double quoted string splits up the string into substrings using normal space and horizontal tab as string delimiters and assigns just first space/tab separated string to the specified loop variable. This string splitting behavior is modified with tokens=1* delims=- to split the file name string on hyphens instead of spaces/tabs with ignoring hyphens at beginning of file name and assigning the string up to first hyphen inside the file name to specified loop variable B and everything after first (sequence of) hyphen(s) to next loop variable according to ASCII table without any further string splitting which is loop variable C.
In other words on a file name like Artist - title the string Artist  with a space at end is assigned to loop variable B and the string  title with a space at beginning is assigned to loop variable C. The two unwanted spaces need to be removed. This can be done using string substitution. But this must be done using delayed expansion not yet enabled because of file names containing an exclamation mark should be also processed correct. For that reason delayed environment variable expansion is next enabled inside the inner FOR loop.
The first IF condition checks if last character of artist string is really a space character and runs the string substitution to remove this space at end of artist string if this condition is true.
The second IF condition first checks if an environment variable Title is defined at all because of the commands of inner FOR loop are also executed on file name does not contain a hyphen at all in which case %%C expands to an empty string and so environment variable Title is deleted from list of environment variables.
The nested third IF condition checks if first character of value of defined environment variable Title is a space and runs the string substitution to redefine Title without first character if this condition is true.
Now artist and title strings can be output before delayed expansion is disabled again by restoring previous environment. Please read this answer for details about the commands SETLOCAL and ENDLOCAL and what exactly happens on each execution of SETLOCAL and ENDLOCAL because of there is much more done than just enabling and disabling delayed environment variable expansion on each found file name.
Note: The title part can contain also the character sequence space, hyphen, space as well as one or more hyphens, but of course the artist string should not contain a hyphen as this character is interpreted as separator between artist and title independent on spaces existing around the hyphen or not. Windows command processor is not designed for enhanced string manipulations like other script interpreters. A different code would be necessary if the condition for splitting file name in artist and title must be space, hyphen, space and not just hyphen.
Other batch file code using  -  to split file name into artist and title strings:
#echo off
setlocal EnableExtensions DisableDelayedExpansion
for /R %%A in (*.mkv *.avi *.mp4) do call :ProcessFileName "%%~nA"
endlocal
goto :EOF
:ProcessFileName
set "FileName=%~1"
set "Title=%FileName:* - =%"
setlocal EnableDelayedExpansion
set "Artist=!FileName: - %Title%=!"
echo Artist=!Artist!
echo Title=!Title!
endlocal
goto :EOF
But this solution using just string substitutions in a subroutine does not work on title string containing an equal sign used as delimiter on string substitution. It is also much slower in comparison to above batch file solution on processing a large amount of file names.
For understanding the used commands and how they work, open a command prompt window, execute there the following commands, and read entirely all help pages displayed for each command very carefully.
call /?
echo /?
endlocal /?
for /?
goto /?
if /?
set /?
setlocal /?
See also Where does GOTO :EOF return to?
Assuming your title always have only a single - splitting artist from title:
#echo off
setlocal enabledelayedexpansion
for /r %%a in (*.mkv *.avi *.mp4) do (
set "fname=%%~na"
set "fname=!fname: - =-!"
for /f "tokens=1,2 delims=-" %%i in ("!fname!") do (
echo The artist is %%i
echo The title is %%j
echo The extension is %%~xa
)
)
We replace the space-space with a - and then delimit on it.

Find and replace line starts with specific value in text file via windows batch file

Even after deep Googeling I can't solve my problem.
Have a text file named test.txt. What I need is to change the line starts with the word "Root:" with other content - using batch file.
setLocal EnableDelayedExpansion
FINDSTR /B Root: test.txt
::returns the correct line - works well
for /f %%i in ('FINDSTR /B Root: test.txt') do set root=%%i
echo %root%
::echos "Root:" - instead of the line content
FOR /F "tokens=*" %%G IN (test.txt) DO
(set x=%%G
if !x!==%root% set x=Hello
echo !x! >> test.txt)
::The syntax of the command is incorrect.
How do i can do it?
EDIT:
Based on Magoo and on RobW at Batch / Find And Edit Lines in TXT file - my problem solved as below:
for /f "tokens=*" %%i in ('"FINDSTR /B Root: test.txt"') do set root=%%i
::root holds test.txt's line starts with "Root:"
echo %root%
SETLOCAL=ENABLEDELAYEDEXPANSION
::iterate on test.txt's lines and compare to the root's value
rename test.txt test.tmp
for /f "tokens=*" %%a in (test.tmp) do (
set foo=%%a
echo !foo!
echo %root%
echo "%root%"
if "!foo!"=="%root%" (set foo=hello)
echo !foo! >> test.txt)
del test.tmp
Thanks!
Roni
#ECHO OFF
SETLOCAL
SET "sourcedir=U:\sourcedir"
SET "filename1=%sourcedir%\q34900978.txt"
FINDSTR /B Root: "%filename1%"
::returns the correct line - works well
FOR /f "tokens=*" %%i IN (
'FINDSTR /B Root: "%filename1%"
') do set "root=%%i"
echo %root%
::echos "Root:" - instead of the line content
FOR /F "usebackqdelims=" %%G IN ("%filename1%") DO (
if "%%G"=="%root%" (
ECHO(x=Hello
) ELSE (
ECHO(%%G
)
)
GOTO :EOF
You would need to change the setting of sourcedir to suit your circumstances.
I used a file named q34900978.txt containing some dummy data for my testing.
The tokens=* option in the for...%%i (or delims=) assigns the entire line to "token 1" and thence to the metavariable %%i.
The default is to assign token 1 but using [SpaceTab,;] as separators, hence you get just the string Root: with your code (up to, but not including the default separators)
See
for /?
from the prompt for documentation.
The syntax SET "var=value" (where value may be empty) is used to ensure that any stray trailing spaces are NOT included in the value assigned. set /a can safely be used "quoteless".
Next step is to process the file. Same story (but since I quote filenames and provide full paths, I need the usebackq option.
The entire line is assigned to %%G (note: except empty lines and lines which begin ;
Then it's a simple if statement - if "the line content"=="target content". The quotes are required because quotes group "strings containing separators" into one string and if syntax is if string operator string2 (dothis) else (dothat)`
Note that the opening parenthesis must be on teh same physical line as the do and the same goes for if. else, the preceding close-parenthesis and the succeeding open-parenthesis must all be on the same physical line with a space between them.
Note the use of ECHO( which will echo an empty line if %%G (in this case) has no value. The ( is not counted as far as nesting is concerned.
(%%G here must have a value - but in the general case, echo %var% will yield echo is on/off if var is undefined, but echo(%var% will cleanly produce a new line)

How to find a word in a text file and delete the line containing the word and the next two lines?

I want to find a word in a text file using a batch file and then I want to remove that line containing the word and also delete some other lines below for example:
_italic_ or **bold**
put returns between paragraphs
indent code by 4 spaces
indent code by 4 spaces
_italic_ or **bold**2
so the result should be:
_italic_ or **bold**
_italic_ or **bold**2
You can try this batch code:
#echo off
set skipline=2
set search=returns
set File=Input.txt
setlocal EnableDelayedExpansion
for %%a in ("%File%") do (
set linecount=1
set skip=0
For /f "usebackq tokens=* delims=" %%b IN (`type "%%a" ^| find /V /N ""`) do (
set a=%%b
set a=!a:*]=!
if "!a!" NEQ "" (
set search=!a:%search%=!
if "!search!" NEQ "!a!" set /a skip=%skipline%+!linecount!
)
if !linecount! GTR !skip! echo(!a!
set /a linecount+=1
)>>tmp
move /Y "tmp" "%%a">Nul
)
EndLocal
exit
This is working with a file containing blank lines and multiple line.
Change set skipline=2 for how many line to skip after find a word you search.
And for multiple files just change set File=Input.txt.
Example for file with extension .txt in current directory:
set File=*.txt
#echo off
setlocal EnableDelayedExpansion
rem Get the number of lines before the one that contain "returns"
for /F "delims=:" %%a in ('findstr /N "returns" input.txt') do set /A "lines=%%a-1"
rem Open a code block to read from input.txt and write to output.txt
< input.txt (
rem Read and write the first "lines" lines
for /L %%i in (1,1,%lines%) do (
set "line="
set /P "line="
echo(!line!
)
rem Omit the number of desired lines (3 in this example)
for /L %%i in (1,1,3) do set /P "line="
rem Copy the rest of lines
findstr "^"
) > output.txt
rem Replace the original file by the new one
move /Y output.txt input.txt
Here is a batch code for this task working only for an input text file not containing empty lines as those lines are skipped by command FOR.
It removes all blocks with 3 lines whereby first line contains returns.
#echo off
setlocal EnableExtensions EnableDelayedExpansion
set "SkipLineCount=0"
set "OutputFile=OutputTextFile.txt"
del "%OutputFile%" 2>nul
for /F "usebackq eol=^ delims=" %%I in ("InputTextFile.txt") do (
if !SkipLineCount! EQU 0 (
set "Line=%%I"
set "Line=!Line:returns=!"
if "!Line!" NEQ "%%I" ( set "SkipLineCount=1" ) else echo(%%I>>"%OutputFile%"
) else (
set /A SkipLineCount+=1
if !SkipLineCount! EQU 3 set "SkipLineCount=0"
)
)
move /Y "%OutputFile%" "InputTextFile.txt"
endlocal
This batch file processes each non empty line. Command FOR skips automatically all lines not containing any character.
Note 1: eol=^ in line with command FOR is necessary to read in and output also lines just containing commas or semicolons which otherwise would be also ignored by command FOR.
The current line is assigned to variable Line if currently no lines should be skipped. Next all occurrences of the word returns are removed case-insensitive from the line if the line contains at least one returns.
The line is ignored if the string of variable Line is not equal after the string replace with unmodified line read from file because this means the line contains at least one returns.
Otherwise the line read from input file is appended to output file.
Note 2: ( between echo and %%I is used here to output also input lines containing only 1 or more spaces or tabs as otherwise with a space instead of ( the command echo would write for such a case its current state OFF into the output file instead of the spaces/tabs read from input file.
The next 2 lines after a line with at least one returns are also ignored for being copied to output file.
As last command the created output file with the 3 lines removed is moved over the input text file.
For understanding the used commands and how they work, open a command prompt window, execute there the following commands, and read entirely all help pages displayed for each command very carefully.
del /?
echo /?
for /?
if /?
move /?
set /?
setlocal /?
Read also the Microsoft article about Using Command Redirection Operators.

Find and type/ display a random textfile with a batchfile

Hello I'm trying to complete a batchfile im working on.
I have a library of motivational quotes textfiles, and i want my batchfile to pick one random quote textfile and display it in the command window. with the command type i guess.
my path to the folder with the quotes is:
C:\Users\niv\Documents\test\scripts\quotes
inside there is :
Quote 1.txt
Quote 2.txt
Quote 3.txt.
i did the command: `type "C:\Users\niv\Documents\test\scripts\quotes\quote1.txt"
that only displayed the selected quote1.txt ofcourse.
If possible i want to get the selected Quote-text file to be a variable so i can use it for different tasks in my batchfile like:
after receiving the selected quote do this command with a program that makes it possible for my computer to read anything after "". like this
%speech% "%quotes%"
the %speech% lets my computer speak whats inside the quotation marks.
i hope you can understand what im trying to accomplish here if not just ask :)
I am assuming each quote is contained in a single line in each file. I recommend placing all the quotes in a single file named quotes.txt, with one quote per line. This should make it easier to maintain the quotes. Then all you need is code that will count the number of lines in the file, and then randomly pick a line between 1 and count.
The FIND /C command can count the number of lines in a file.
The %RANDOM% dynamic variable gives a pseudo random number between 0 and 32767, and the modulo SET /A operator can be used to convert the value into a number between 0 and count-1.
The FOR /F command reads lines from a file, and you can use the SKIP option to skip a random number of lines.
quotes.txt
quote 1
quote 2
quote 3
quote 4
randomQuote.bat
#echo off
setlocal
:: Count the number of quotes and define a random number to skip
for /f %%N in ('find /c /v "" ^<quotes.txt') do set /a skip=%random% %% %%N
if %skip% gtr 0 (set skip=skip=%skip%) else set "skip="
:: Read a random quote into a variable
for /f "%skip% delims=" %%A in (quotes.txt) do (
set "quote=%%A"
goto :break
)
:break
:: Echo the quote (or do whatever you need)
echo %quote%
You can read a text file into a variable like this:
setlocal EnableDelayedExpansion
set filename=Quote 1.txt
for /f "tokens=*" %%a in ('type "%filename%"') do (
set quote=!quote!%%a^
)
echo !quote!
endlocal
The trailing ^ in set quote=!quote!%%a^ followed by an empty line ends each appended line with a newline. If you don't need the newlines, you could replace
for /f "tokens=*" %%a in ('type "%filename%"') do (
set quote=!quote!%%a^
)
with
for /f "tokens=*" %%a in ('type "%filename%"') do (
set quote=!quote! %%a
)
to get the whole quote in a single line.
In any case you need delayed expansion for this (!quote! instead of %quote%).
My answer focuses on counting the number of text files in the path you provided, then choosing a random quote number and typing the quote. both of the previous answers can be used as reference for inserting the quote into a variable (which my code does not provide):
#Echo off
set path=C:\Users\niv\Documents\test\scripts\quotes
cd /D %path%
setLocal EnableDelayedExpansion
set count=0
for %%a in (*.txt) do (
set /a count=!count!+1
)
echo Total number of quote files: %count%
set /a num=(%count% * %random%) / 32768 + 1
echo Quote #: %num%
type "%path%\quote %num%.txt"
endlocal

Resources