Coding two real time progress bars in batch - windows

I really like the progress bar that #MCND coded in this post - Coding a real time progress bar in batch
Is there any way to add a second real-time progress bar just below the first one which could be manipulated seperately showing the overall progress of the batch file, while the first progress bar shows the real-time progress of the current function?
I tried copying the :drawProgressBar, :initProgressBar and :finalizeProgressBar subroutines and adding a 1 to the end of them and all pb variables in the subroutines to create a distinct subroutine, but no luck.
#MCND 's original post/code:
Just a skelleton. Adapt as needed.
The basic idea is to output the line with the progress bar with an ending carriage return to return to the start of the line and be able to repaint the next state over the previous one.
All "problematic" code wrapped into subroutines so you only need to call :drawProgressBar percentValue "operationText"
#echo off
setlocal enableextensions disabledelayedexpansion
for /l %%f in (0 1 100) do (
call :drawProgressBar %%f "up test with a long text that will not fit on screen unless you have a lot of space"
)
for /l %%f in (100 -1 0) do (
call :drawProgressBar %%f "going down test"
)
for /l %%f in (0 5 100) do (
call :drawProgressBar !random! "random test"
)
rem Clean all after use
call :finalizeProgressBar 1
call :initProgressBar "|" " "
call :drawProgressBar 0 "this is a custom progress bar"
for /l %%f in (0 1 100) do (
call :drawProgressBar %%f
)
endlocal
exit /b
:drawProgressBar value [text]
if "%~1"=="" goto :eof
if not defined pb.barArea call :initProgressBar
setlocal enableextensions enabledelayedexpansion
set /a "pb.value=%~1 %% 101", "pb.filled=pb.value*pb.barArea/100", "pb.dotted=pb.barArea-pb.filled", "pb.pct=1000+pb.value"
set "pb.pct=%pb.pct:~-3%"
if "%~2"=="" ( set "pb.text=" ) else (
set "pb.text=%~2%pb.back%"
set "pb.text=!pb.text:~0,%pb.textArea%!"
)
<nul set /p "pb.prompt=[!pb.fill:~0,%pb.filled%!!pb.dots:~0,%pb.dotted%!][ %pb.pct% ] %pb.text%!pb.cr!"
endlocal
goto :eof
:initProgressBar [fillChar] [dotChar]
if defined pb.cr call :finalizeProgressBar
for /f %%a in ('copy "%~f0" nul /z') do set "pb.cr=%%a"
if "%~1"=="" ( set "pb.fillChar=#" ) else ( set "pb.fillChar=%~1" )
if "%~2"=="" ( set "pb.dotChar=." ) else ( set "pb.dotChar=%~2" )
set "pb.console.columns="
for /f "tokens=2 skip=4" %%f in ('mode con') do if not defined pb.console.columns set "pb.console.columns=%%f"
set /a "pb.barArea=pb.console.columns/2-2", "pb.textArea=pb.barArea-9"
set "pb.fill="
setlocal enableextensions enabledelayedexpansion
for /l %%p in (1 1 %pb.barArea%) do set "pb.fill=!pb.fill!%pb.fillChar%"
set "pb.fill=!pb.fill:~0,%pb.barArea%!"
set "pb.dots=!pb.fill:%pb.fillChar%=%pb.dotChar%!"
set "pb.back=!pb.fill:~0,%pb.textArea%!
set "pb.back=!pb.back:%pb.fillChar%= !"
endlocal & set "pb.fill=%pb.fill%" & set "pb.dots=%pb.dots%" & set "pb.back=%pb.back%"
goto :eof
:finalizeProgressBar [erase]
if defined pb.cr (
if not "%~1"=="" (
setlocal enabledelayedexpansion
set "pb.back="
for /l %%p in (1 1 %pb.console.columns%) do set "pb.back=!pb.back! "
<nul set /p "pb.prompt=!pb.cr!!pb.back:~1!!pb.cr!"
endlocal
)
)
for /f "tokens=1 delims==" %%v in ('set pb.') do set "%%v="
goto :eof

Related

Batch - get content between two strings

I have string like this
<AdaptationSet maxHeight="576" maxWidth="1024" mimeType="video/mp4" id="0" segmentAlignment="true" startWithSAP="1">
<ContentProtection schemeIdUri="urn:uuid:edef8ba9-79d6-4ace-a3c8-27dcd51d21ed" cenc:default_KID="bcf950eb-a062-5b0d-b1f2-fed53f20ba10">
<cenc:pssh>AAAATHBzc2gAAAAA7e+LqXnWSs6jyCfc1R0h7QAAACwiJGFlNWU5NTk4LWU5ODktNWM1Ny1iOTk2LTg3OTA4NWIyYzUxNUjj3JWbBg==</cenc:pssh>
</ContentProtection>
<ContentProtection schemeIdUri="urn:mpeg:dash:mp4protection:2011" value="cenc" cenc:default_KID="bcf950eb-a062-5b0d-b1f2-fed53f20ba10" />
<SegmentTemplate duration="6000" initialization="$RepresentationID$/video/init.mp4" media="$RepresentationID$_184201/segment_$Number$.m4s" startNumber="0" timescale="1000" />
<Representation bandwidth="247600" codecs="avc1.64001F" height="144" width="256" id="ae5e9598-e989-5c57-b996-879085b2c515-0_video_frag_auto.idx~video_frag_auto~481" scanType="progressive" />
I want to get output like below and put it into a variable.
ae5e9598-e989-5c57-b996-879085b2c515
Note that there is already id="0" in the first line and I want to extract value of id partially for the last line.
Is there an easy way to do this in batch?
If you must use batch, here's one example to get started. This extracts all values id from file ooo.txt that contains your string.
#echo off
setlocal enabledelayedexpansion
set x=0
for /f "eol=> tokens=* usebackq delims= " %%i in (`type ooo.txt`) do (
set x=0
set XXX=XXX
for %%I in (%%i) do (
if "%%I"=="id" (
set x=1
) else (
if !x! EQU 1 (
set x=0
set XXX=%%I
)
)
)
set XXX=!XXX:"=!
if not "!XXX!"=="XXX" (
set XXX=!XXX:"=!
rem echo !XXX!
call :enumerate !XXX! YYY
echo !YYY!
)
)
goto :eof
:enumerate
set pos=0
set Y=%1
set result=
set part=
:countchar
if not "!Y:~%pos%,1!"=="" (
set /a pos=pos+1
if "!Y:~%pos%,1!"=="-" (
set result=!result!!part!
set part=
)
set part=!part!!Y:~%pos%,1!
goto :countchar
)
set %~2=!result!
exit/b
:eof
endlocal
This outputs
ae5e9598-e989-5c57-b996-879085b2c515
and, within the loop, stores each id in variable YYY (although the first one is empty).
This assumes you want to keep everything up to but not including the last hyphen -.
Here's a 'for fun' example, which, as you've provided no code yourself, will not be modified post answer, and no support, or explanation, will be undertaken either.
#For /F Delims^= %%G In ('%__AppDir__%findstr.exe /i "id=\"[a-e0123456789]*-[a-e0123456789]*-[a-e0123456789]*-[a-e0123456789]*-[a-e0123456789]*-" "xmlfile.mpd"'
) Do #Set "}=%%G" & SetLocal EnableDelayedExpansion & For /F UseBackTokens^=2-6Delims^=-^" %%H In ('!}:* id^=^"^=!') Do #Endlocal & Set "id=%%H-%%I-%%J-%%K-%%L"
#(Set id) 2>NUL & Pause
You will probably want to change the source filename from xmlfile.mpd, and can optionally remove the last line, which was included just to allow you to see if it worked!
#ECHO OFF
SETLOCAL
rem The following settings for the source directory, destination directory, target directory,
rem batch directory, filenames, output filename and temporary filename [if shown] are names
rem that I use for testing and deliberately include names which include spaces to make sure
rem that the process works using such names. These will need to be changed to suit your situation.
SET "sourcedir=u:\your files"
SET "filename1=%sourcedir%\q65892027.txt"
SET "capture="
SET "captured="
FOR /f "usebackqdelims=" %%b IN ("%filename1%") DO (
FOR %%c IN (%%b) DO (
IF /i "%%~c"=="scantype" SET "capture="&IF DEFINED captured GOTO done
IF DEFINED capture SET "captured=%%~c"
IF /i "%%~c"=="id" SET "capture=Y"
)
)
:done
ECHO captured "%captured%"
GOTO :EOF
setlocal enabledelayedexpansion
echo:
set "td=%~dp0"
set "pattern= id="
set "id=id"
call:getPatternLength "!id!" plen
set /a "slen=!plen!-1"
set "opt=tokens=1,2,* delims=<"
for /f "tokens=* delims=" %%z in (' type "!td!usedata\id.txt"^| findstr /c:"!pattern!" ') do (
for /f "%opt%" %%b in ("%%z") do (
for /f "tokens=* delims=" %%y in ('echo/%%b^|findstr /v [0-9][a-z]') do (
set "bempty=true"
call:findit "%%c" "!id!" strfound
)
if not defined bempty call:findit "%%b" "!id!" strfound
set "strfound=!strfound:"=!"
if defined strfound (
call:handlefound "!strfound!" result
if defined result (echo Finally: !result! & exit /b 0)
)
)
)
:end
endlocal
exit /b 0
:getPatternLength
set "str=%~1"
set /a "count=0"
:next
for /f "tokens=* delims=" %%z in ('echo/!str!') do (
set /a "count+=1"
set "str=!str:~1!"
if not "!str!"=="" goto:next
)
set "%2=!count!"
if /i "%0"==":getPatternLength" (exit /b 0)
:handlefound
set "str=%~1"
for /f "tokens=* delims=" %%a in ('echo/!str!^| findstr [a-z]') do (
:notyet
for /f "tokens=1,2,* delims=-" %%d in ("!str!") do (
for /f "tokens=* delims=" %%g in ('echo/%%e^|findstr "_"') do (
set "res=!res!-%%d"
set "%2=!res!"
exit /b 0
)
if not defined res ( set "res=%%d" ) else ( set "res=!res!-%%d")
set "str=%%e-%%f" & goto:notyet
)
)
echo Not the right line.. next.
exit /b 1
:findit
set "str=%~1"
set "find=%~2"
set "opts=tokens=1,* delims= "
set "opts2=tokens=1,* delims=="
:nexttoken
for /f "%opts%" %%m in ("!str!") do (
for /f "%opts2%" %%o in ("%%m") do (
if "%%o"=="!find!" (
set "%3=%%p"
if "%0"==":findit" exit /b 0
)
set "str=%%n" & goto:nexttoken
)
)
exit /b 1

Output filename and count of a directory in a text file - windows

I have a batch to output filename and count of filenames with the same prefix and date in a text file.
E.g.
Q1231111.zip
Q1241111.zip
where:
Q123 - is a prefix
1111 - is a date.
I want an output such as:
123 : 1
124 : 1
125 : 0
But the batch file unable to output the last one. I wanna see the file is present so i need the 0 output.
Here's my code:
#echo off
setlocal EnableExtensions
for %%I in ("Z:\StoreDataJDA\Q1231111.zip") do call :CountFile "%%~nI"
for %%I in ("Z:\StoreDataJDA\Q1241111.zip") do call :CountFile "%%~nI"
for %%I in ("Z:\StoreDataJDA\Q1251111.zip") do call :CountFile "%%~nI"
for /F "tokens=2,3 delims=#=" %%I in ('set Group# 2^>nul') do echo %%I: %%J >>count.txt
endlocal
goto :EOF
:CountFile
set "FileName=%~1"
set "FileGroup=%FileName:~1,4%"
if "Group#%FileGroup%" == "" (
set "Group#%FileGroup%=1"
) else (
set /A Group#%FileGroup%+=1
)
goto :EOF
pause
Thanks in advance!
From your description, it's hard to tell exactly what you are looking for. But by looking at your very similar question from a year ago, and from Gerhard's comment, I think what you're looking for is:
Count the number of files with a given prefix, each file having a different date suffix.
I think this should do it:
#echo off
setlocal EnableExtensions
set "Group#123=0" & for %%I in ("Z:\StoreDataJDA\Q123????.zip") do call :CountFile "%%~nI"
set "Group#124=0" & for %%I in ("Z:\StoreDataJDA\Q124????.zip") do call :CountFile "%%~nI"
set "Group#125=0" & for %%I in ("Z:\StoreDataJDA\Q125????.zip") do call :CountFile "%%~nI"
(for /F "tokens=2,3 delims=#=" %%I in ('set Group# 2^>nul') do echo %%I: %%J)>count.txt
endlocal
goto :EOF
:CountFile
set "FileName=%~1"
set "FileGroup=%FileName:~1,3%"
set /A Group#%FileGroup%+=1
goto :EOF

Why is the array filled with "m"

I'm fairly new to batch and I've been trying to write some simple sorting programs. This program uses the most basic sorting system, and the code(from what I can see) seems to be error-free. Yet when I run it, a random list is generated, and it seems as if some sorting is going on, then the array is filled with the letter "m". I don't see why this is occurring, so if somebody could point me in the correct direction I would greatly appreciate it.
My code:
#echo off
color b
title sorting
set ar=0
set num=0
set check=0
set checknum=0
set totalnumber=500
set randmax=5000
:array
if %num% LSS %totalnumber% (
set /A a[%num%]=%random% %% %randmax%
set /A num=%num%+1
goto array
)
if %num% EQU %totalnumber% (
goto echo1
)
:echo1
for /F "tokens=2 delims==" %%s in ('set a[') do echo %%s
echo sort initialized
goto sort
)
:sort
set n=0
:sortloop
set /A m=%n%+1
if %n% EQU %totalnumber% (
goto check
)
if %a[%n%]% GTR %a[%m%]% (
set hold=%a[%m%]%
set a[%m%]=%a[%n%]%
set a[%n%]=%hold%
set /A n=%n%+1
goto sortloop
)
if %a[%n%]% LSS %a[%m%]% (
echo a[%n%] check
set /A n=%n%+1
goto sortloop
)
:check
set check=0
set checknum=0
:checkloop
set /A checknumplus=%checknum%+1
if %check% EQU %totalnumber% (
goto complete
)
if %checknum% EQU %totalnumber% (
set n=0
goto sort
)
if %a[%checknum%]% LSS %a[%checknumplus%]% (
set /A check=%check%+1
set /A checknum=%checknum%+1
goto checkloop
)
:complete
for /F "tokens=2 delims==" %%s in ('set a[') do echo %%s
for /F "tokens=2 delims==" %%s in ('set a[') do echo %%s > sortedlist.txt
When you need to use variables inside of variables in batch (most commonly when working with arrays), you need to use delayed expansion.
Right now, your code says set hold=%a[%m%]%. The interpreter is treating this value as the variable %a[% (which doesn't exist, so it using nothing), the literal character m, and the variable %]% (which also doesn't exist and is therefore empty).
To get around this, put setlocal enabledelayedexpansion at the top of your code and then change your set statement to set hold=!a[%m%]! (and do the same thing with the other lines that are using it).

BATCH- binary with for

I have to make a script that has to calculate the mask and the net, so I'm trying a script with for but it can not convert the IP to binary. I think I'm not using the variables right.
Any ideas?
#echo off
setlocal enabledelayedexpansion
set var=%1
set /p var=Introduce la ip:
for /F "tokens=1 delims=." %%a in ("%var%") do (
echo %%a
set "vara=%%a"
:binario
set bin=2
set /a resto=%vara%%%bin%
set /a a=%vara%/%bin%
set resultado=%resto%%resultado%
if %vara% GTR 0 (goto binario)
echo %resultado%
goto siguiente
)
:siguiente
for /F "tokens=2 delims=." %%b in ("%var%") do (
echo %%b
)
for /F "tokens=3 delims=." %%c in ("%var%") do (
echo %%c
)
for /F "tokens=4 delims=." %%d in ("%var%") do (
echo %%d
)
goto fin
:vacio
echo Error!
goto fin
:fin
pause
You've got a few minor problems that I see. You set var=%1 but you never check to see whether %1 was supplied before doing set /p var=Enter an IP:. You never call or goto :vacio. As I commented above, modulos within batch scripts need to be written as %% to prevent evaluation as variable chararacters. You don't need % in var names in set /a commands, and you can combine multiple set /a statements with a comma. So instead of
set /a resto=%vara%%%bin%
set /a a=%vara%/%bin%
(which is wrong anyway -- I'll get to that in a minute), I suggest this would be more understandable and maintainable:
set /a resto = vara %% bin, numero = vara / bin
The biggest problem is that you appear to be trying to modify %%a. Don't do that.
If I were you, I would move the decimal to binary conversion to a subroutine, and call it for each octet. Try this:
#echo off
setlocal enabledelayedexpansion
set IP=%1
if "%IP%"=="" set /p "IP=Introduce la ip: "
set idx=0
for %%a in (%IP:.= %) do (
if %%a lss 0 goto vacio
if %%a gtr 255 goto vacio
if !idx! gtr 3 goto vacio
set /P "=%%a = "<NUL
call :dec2bin bin[!idx!] %%a
set /a idx += 1
)
echo %bin[0]%.%bin[1]%.%bin[2]%.%bin[3]%
goto fin
:dec2bin <var_para_definir> <numero>
setlocal enabledelayedexpansion
set numero=%~2
set bin=
for /L %%I in (1,1,8) do (
set /a bit = numero %% 2, numero /= 2
set bin=!bit!!bin!
)
echo %bin%
endlocal & set "%~1=%bin%"
goto :EOF
:vacio
echo Error!
goto fin
:fin
pause
For more information about using call as a function that returns a value, see this page.

Batch file needed for comparing two files

This is my requirement in windows batch file I tried the following
Example:
f1.txt
sam
varun
ramesh
babu
f2.txt
babu
sam
I need the output of
varun
ramesh
The program
#echo on
SETLOCAL EnableDelayedExpansion
for /F "tokens=* delims=." %%a in (f1.txt) do (
call :myInnerLoop "%%a"
)
echo out of inner loop
)
goto :eof
:myInnerLoop
for /F "tokens=* delims=." %%b in (f2.txt) do (
if "%~1"=="%%b" (
echo inside inner loop
goto :next
) else (
echo %%a >> "E:\test\diff.txt"
)
:next
goto :eof
But it is not working kindly help me.
Even I tried diff utility also from http://gnuwin32.sourceforge.net/packages/diffutils.htm no help.
Your code is almost correct, but you have some () wrong. Try this one:
#echo off
del d:\test\windows\comp\diff.txt
SETLOCAL EnableDelayedExpansion
for /F "tokens=* delims=." %%a in (f1.txt) do (
echo %%a
call :myInnerLoop "%%a"
)
echo out of inner loop
goto :eof
:myInnerLoop
for /F "tokens=* delims=." %%b in (f2.txt) do (
echo "x: " %~1
echo "y: " %%b
if "%~1"=="%%b" (
echo next
goto :next
)
)
echo "Log " %~1
echo %~1 >> "d:\test\windows\comp\diff.txt"
:next
goto :eof
Are you looking for the comp command?
Compares the contents of two files or sets of files.
COMP [data1] [data2] [/D] [/A] [/L] [/N=number] [/C] [/OFF[LINE]]
data1 Specifies location and name(s) of first file(s) to compare.
data2 Specifies location and name(s) of second files to compare.
/D Displays differences in decimal format.
/A Displays differences in ASCII characters.
/L Displays line numbers for differences.
/N=number Compares only the first specified number of lines in each file.
/C Disregards case of ASCII letters when comparing files.
/OFF[LINE] Do not skip files with offline attribute set.
To compare sets of files, use wildcards in data1 and data2 parameters.
The best way to compare files in both directions
#echo off
::*********-Code by S-S Guca Srbija 2019-*********
title File-Compare by s-s
mode con cols=41 lines=10 & color 09
Set "File1a=File1.txt"
Set "File2b=File2.txt"
Set "Result=CompareResult.txt"
::************************************************
Set "File1b=%File1a%"
Set "File2a=%File2b%"
:Start
cls
set "Write=0"
Set /a "Test1+=1"
Echo(
Echo(=========================================
Echo( I compare Files %File1a% To %File2b%
Echo(=========================================
FOR /F "delims=" %%A in (%File1a%) do (
Set /a "LineNum1+=1"
Call :EXloop "%%A"
)
IF "%Test1%"=="2" Goto:End
Set "File1a=%File2a%"
Set "File2b=%File1b%"
Set "LineNum1="
Set "LineNum2="
Goto:Start
:End
EXIT
:EXloop
FOR /F "delims=" %%B in (%File2b%) do (
IF "%~1"=="%%B" goto:next
)
Set "LineNum2=0"
FOR /F "delims=" %%C in (%File2b%) do (
Set "MyFiles=%%C"
Call :LineCount
)
Goto:next1
:LineCount
Set /a "LineNum2+=1"
IF "%LineNum2%"=="%LineNum1%" (
set "File2=%MyFiles%"
)
goto:eof
:next1
Echo(>> "%Result%"
IF "%Test1%"=="1" (
set /a "Write+=1"
IF "%Write%"=="0" (
Echo( They were compared %File1a% To %File2b%>> "%Result%"
)
)
IF "%Test1%"=="2" (
set /a "Write+=1"
IF "%Write%"=="0" (
Echo( They were compared %File1a% To %File2b%>> "%Result%"
)
)
Echo(>> "%Result%"
Echo(=========================>> "%Result%"
Echo(%File1a%=Line=%LineNum1%=%~1>> "%Result%"
Echo((------------------------)>> "%Result%"
Echo(%File2b%=Line=%LineNum1%=%File2%>> "%Result%"
Echo(=========================>> "%Result%"
:next
goto:eof
::*********-Code by S-S Guca Srbija 2019-*********
OR
#echo off
::*********-Code by S-S Guca Srbija 2019-*********
title File-Compare by s-s
mode con cols=41 lines=10 & color 09
SETLOCAL EnableDelayedExpansion
Set "File1a=File1.txt"
Set "File2b=File2.txt"
Set "Result=CompareResult.txt"
::************************************************
Set "File1b=!File1a!"
Set "File2a=!File2b!"
:Start
cls
set "Write=0"
Set /a "Test1+=1"
Echo(
Echo(=========================================
Echo( I compare Files !File1a! To !File2b!
Echo(=========================================
FOR /F "delims=" %%A in (!File1a!) do (
Set /a "LineNum1+=1"
Call :EXloop "%%A"
)
IF "%Test1%"=="2" Goto:End
Set "File1a=!File2a!"
Set "File2b=!File1b!"
Set "LineNum1="
Set "LineNum2="
Goto:Start
:End
SETLOCAL DisableDelayedExpansion
EXIT
:EXloop
FOR /F "delims=" %%B in (!File2b!) do (
IF "%~1"=="%%B" goto:next
)
Set "LineNum2=0"
FOR /F "delims=" %%C in (!File2b!) do (
Set "MyFiles=%%C"
Call :LineCount
)
Goto:next1
:LineCount
Set /a "LineNum2+=1"
IF "%LineNum2%"=="%LineNum1%" (
set "File2=!MyFiles!"
)
goto:eof
:next1
Echo(>> "!Result!"
IF "%Test1%"=="1" (
set /a "Write+=1"
IF "%Write%"=="0" (
Echo( They were compared !File1a! To !File2b!>> "!Result!"
)
)
IF "%Test1%"=="2" (
set /a "Write+=1"
IF "%Write%"=="0" (
Echo( They were compared !File1a! To !File2b!>> "!Result!"
)
)
Echo(>> "!Result!"
Echo(=========================>> "!Result!"
Echo(!File1a!=Line=!LineNum1!=%~1>> "!Result!"
Echo((------------------------)>> "!Result!"
Echo(!File2b!=Line=!LineNum1!=!File2!>> "!Result!"
Echo(=========================>> "!Result!"
:next
goto:eof
::*********-Code by S-S Guca Srbija 2019-*********
:: Modify the code as you needed

Resources