how can i add a comma to the bitrate variable in windows batch? (without using powershell)
examples:
2 000 kb/s => 2,000 kb/s (replace the space with a comma)
876 kb/s => 876 kb/s (no change)
10.1 MB/s => 10.1 MB/s (no change)
is it possible to do it in a simple 1 or 2-liner?
also, the bitrates varies from each video. it is not fixed.
thank you!
This is a "simple 1 or 2 liner" solution that works on numbers (not bitrates) upto 9 digits each. It also offers the additional feature of align (right justify) the converted numbers. If you want not the alignment, just eliminate the spaces (via a for command, for example).
#echo off
setlocal EnableDelayedExpansion
rem Initialize data, just once
set "c = " & for /L %%i in (0,1,9) do set "c%%i=,"
rem Generate a series of test numbers between 1 and 9 digits, with two optional decimals
for /L %%i in (1,1,10) do (
set "num=!random!!random!"
for %%d in (!random:~-1!) do if %%d gtr 0 set "num=!num:~0,%%d!"
if !random:~-1! geq 5 set "num=!num!.!random:~-2!"
call :insertCommas !num!
)
goto :EOF
:insertCommas num
for /F "tokens=1* delims=." %%a in ("%1") do set "int= %%a" & if "%%b" equ "" (set "frc= ") else set "frc=.%%b"
echo %int:~-9%%frc% = %int:~-9,3%!c%int:~-7,1%!%int:~-6,3%!c%int:~-4,1%!%int:~-3%%frc%
exit /B
Output example:
1719 = 1,719
155292712 = 155,292,712
3269828.90 = 3,269,828.90
1300 = 1,300
254112572.84 = 254,112,572.84
1.98 = 1.98
269462 = 269,462
1637 = 1,637
13 = 13
153851.04 = 153,851.04
EDIT 2021/12/13: New method as requested by comment
It seems the purpose of this question was misunderstood...
The new code:
#echo off
setlocal EnableDelayedExpansion
for /F "delims=" %%a in (input.txt) do (
set "bitrate=%%a"
set "bitrate=!bitrate: =,!"
echo !bitrate:~0,-5! !bitrate:~-4!
)
Sample input data:
2 000 kb/s
876 kb/s
10.1 MB/s
Output:
2,000 kb/s
876 kb/s
10.1 MB/s
Related
There is a batch file that looks for Pen=n in the list.txt and changes its value (n) randomly from the given row of ten numbers (set "var[pen]=1 2 3 4 5 6 7 8 9 10"). But if there are more than ten numbers say twenty (set "var[pen]=1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20") or hundred, it is still picking a number from first ten ones ignoring the rest.
#echo off
setlocal EnableDelayedExpansion
set "file=D:\list.txt"
set "temp=D:\temp.txt"
set "var[pen]=1 2 3 4 5 6 7 8 9 10" &
for /L %%i in (1,10,1%time:~-2%) do set "rand=!random!"
(for /F "usebackq tokens=1,2 delims==" %%a in ("%file%") do (
if defined var[%%a] (
call :getRandomValue var="!var[%%a]!"
echo %%a=!var!
) else if "%%b" neq "" (
echo %%a=%%b
) else (
echo %%a
)
)) > "%temp%"
move /Y "%temp%" "%file%"
pause > nul && pause > nul
goto :EOF
:getRandomValue value="list"
set /A "rand=!random:~-1!+1"
for /F "tokens=%rand%" %%v in (%2) do set "%1=%%v"
Any help would be appreciated.
edit:
the list.txt contains a list of stuff like pen paper rubber etc. with the corresponding value next to it.
pen=5
pencil=43
paper=0
rubber=22
what the bat file does is just putting random number picking in up from the row of numbers provided. in the following case it would change the value of pen to a random number from 1 to 10. but if I add some extra numbers more than ten it will then just ignore them.
You forgot to specify the origin post of this problem. In such a post, there is not any specification about how the probabilities must be given, but all the 3 examples provided have 10 probable values, so I assumed that all probabilities have 10 values. The fix is add the number of probabilities each value can have:
#echo off
setlocal EnableDelayedExpansion
rem Define the probabilities for new values
set "value[apple]=0 0 0 0 0 0 0 1 1 1" & set "num[apple]=10" & rem 0 (70%) or 1 (30%)
set "value[peach]=0 0 0 0 0 1 2 3 4 5" & set "num[peach]=10" & rem from 0 (50%) to 5 (the rest 50%)
set "value[banana]=54 68 82 96" & set "num[banana]=4" & rem each 25%
rem Randomize
for /L %%i in (1,10,1%time:~-2%) do set "ran=!random!"
(for /F "tokens=1,2 delims==" %%a in (input.ini) do (
if defined value[%%a] (
call :getRandomValue value=%%a
echo %%a=!value!
) else if "%%b" neq "" (
echo %%a=%%b
) else (
echo %%a
)
)) > output.ini
move /Y output.ini input.ini
goto :EOF
:getRandomValue value=item
set /A "ran=%random%%%num[%2]+1"
for /F "tokens=%ran%" %%v in ("!value[%2]!") do set "%1=%%v"
exit /B
You also forget (again) to provide the real format of the input file, that include [headers]:
[Berries]
Strawberry=1
Blackberry=-13
Blueberry=100
Cherry=6
[Fruits]
apple=0
peach=4
banana=18
orange=-2.5
[Vegetables]
Potato=44
Tomato=2
Onion=0
Garlic=17
EDIT 2022/01/08: New method added as requested in comment
As I already said, you have not specified the rules to define the probable values. I proposed a method that works correctly based on your first example, but then you define values that does not conform with my proposed method (10 possible values, like in your first example). I modified the method and then you invented values that does not conform either: "Why 100 values?" "Because any number above 31 will make the method fail..."
I modified the method (again) so you can define the probabilities via value:percent pairs. Here it is:
#echo off
setlocal EnableDelayedExpansion
rem Define the probabilities for new values as value:percent pairs
set "value[apple]=23:17 68:83" & rem 23 at 17%, 68 at 83%
set "value[peach]=0:50 1:10 2:10 3:10 4:10 5:10" & rem from 0 (50%) to 5 (the rest 50%)
set "value[banana]=54:25 68:25 82:25 96:25" & rem each 25%
rem Randomize
for /L %%i in (1,10,1%time:~-2%) do set "ran=!random!"
(for /F "tokens=1,2 delims==" %%a in (input.ini) do (
if defined value[%%a] (
call :getRandomValue %%a
echo %%a=!value!
) else if "%%b" neq "" (
echo %%a=%%b
) else (
echo %%a
)
)) > output.ini
move /Y output.ini input.ini
goto :EOF
:getRandomValue item
set /A "ran=%random%%%100+1, val=0"
for %%a in (!value[%1]!) do for /F "tokens=1,2 delims=:" %%x in ("%%a") do (
if %ran% gtr !val! set "value=%%x"
set /A val+=%%y
)
exit /B
What you are aiming to do is to randomly index from a list, which requires you to first determine the number of items in the list.
one method of doing so:
#Echo off
Set "var[pen]=a b c d e f g h i"
Rem enable enviroment for !expanison!
Setlocal EnableDelayedExpansion
Rem Build 'array', splitting string on spaces and incrementing array size count
Set _i=1& Set "item[1]=%var[pen]: =" & Set /A "_i+=1" & Set "item[!_i!]=%"
Rem index randomly from known array size [one indexed]
For /f delims^= %%i in ('Set /A !random! %%!_i! + 1')Do Echo(Item:%%i = !Item[%%i]!
Pause
I am working on a program, and all of the parts work perfectly except one, that part is supposed to generate a seven digit random number which is divisible by 7.
I am aware that there are similiar questions to mine, but I did not find my anwser within them, and despite trying I was myself only capable of somethimes generating such a number.
Any idea how to do so?
You can use the modulo function (see set /?):
#echo off
setlocal
set "number=%random%%random%%random%%random%%random%%random%%random%"
set "number=%number:~0,7%"
set /a remainder=number %% 7
if %remainder% equ 0 (
echo %number% is a multiple of 7
) else (
echo %number% divided by 7 gives a rest of %remainder%
)
Just in case, leading zero(s) is/are ok or even desired as a possibility:
#echo off
setlocal
set "number=%random%%random%%random%%random%%random%%random%%random%"
set "number=%number:~-7%"
set /a remainder=7%number% %% 7
if %remainder% equ 0 (
echo %number% is a multiple of 7
) else (
echo %number% divided by 7 gives a rest of %remainder%
)
Here's a slightly different method, which is designed to propagate a variable, named D7 with a seven digit value, which when divided by seven will return an exact integer:
This first example allows for leading 0's in the resulting value.
Echo Off
SetLocal EnableExtensions DisableDelayedExpansion
Set "D7="
For /L %%G In (0 1 9) Do For %%H In (
%Random:~-1%%Random:~-1%%Random:~-1%%Random:~-1%%Random:~-1%%Random:~-1%
) Do (Set /A D7 = 7%%H%%G %% 7
SetLocal EnableDelayedExpansion & If !D7! Equ 0 (EndLocal
Set "D7=%%H%%G"
GoTo :Next))
:Next
Set D7
Pause
Please note: It is possible that the resulting value could be 0000000 because leading 0's are allowed and 0 is divisible by every integer.
If you do not want to have leading 0's then a very small adaptation is needed:
#Echo Off
SetLocal EnableExtensions DisableDelayedExpansion
Set "D7="
For /L %%G In (1 1 9) Do For %%H In (
%Random:~-1%%Random:~-1%%Random:~-1%%Random:~-1%%Random:~-1%%Random:~-1%
) Do (Set /A D7 = %%G%%H %% 7
SetLocal EnableDelayedExpansion & If !D7! Equ 0 (EndLocal
Set "D7=%%G%%H"
GoTo :Next))
:Next
Set D7
Pause
i am trying to write a win 10 batch script which monitors a output of numbers in csv, 5 lines like 111.07 112.56 123.66 etc. The output happens every 60sec.
(Optionally i can store that in a log.txt and call that in the script)
Also I want to have the output numbers in absolute values without decimals.
Then do a Less or equal than or greater than ... (LEQ 100 and GEQ 140 -> right?). If in range then immediately reboot shutdown -r -f -t 00 else go to :start again.
I have to admit i have no clue what i am doing and everything i tried just immediately exits the script, even when do a pause or timeout after every step.
EDIT: Here is what i have so far.
:start
FOR /F "tokens=* USEBACKQ" %%i IN ('nvidia-smi.exe --format=csv,nounits,noheader --query-gpu=power.draw') do (SET var=%%i%)
echo %%var%
if %%var% LEQ 100 (echo reboot) else (goto :start)
If %%var% GEQ 140 (echo reboot) else (goo :start)
The First line should store the 5 output lines of (‘nvidia-Smi.exe ….‘) in the variable var.
Output of Nvidia-smi.exe:
117.00
123.34
116.77
128.65
119.45
The second should do the if else comparison and reboot (for now just echo) I do not understand how i can build the if else into the for loop.
The Nvidia-smi.exe seems not to be executed but just to be printed, but when i run the command in a cmd it executes. The commas get removed between cvs,Mounties,noheader
Also i do not understand how to not repeat myself in the if leq … else ….
Output:
C:\Users\admin\Desktop\monitor.bat
C:\Users\admin>FOR /F "tokens=* USEBACKQ" %i IN ('nvidia-smi.exe --format csv nounits noheader --query-gpu power.draw') do (SET var=%i )
C:\Users\admin>(SET var=nvidia-smi.exe --format csv nounits noheader --query-gpu power.draw )
C:\Users\admin>echo %var
%var
Syntaxerror.
C:\Users\admin> if %varstart)
Thanks #Mofi,
with your demonstration i managed to get it right.
:begin
#echo off
Timeout 57
if exist log.txt del log.txt
nvidia-smi.exe --format=csv,nounits,noheader --query-gpu=power.limit --filename=log.txt
for /F "tokens=* delims=" %%I in (log.txt) do for %%J in (%%I) do if %%~nJ LEQ 100 (echo %%J is less or equal 100 && shutdown /r /f /t 60) else if %%~nJ GEQ 140 (echo %%J is greater or equal 140 && shutdown /r /f /t 60) else (echo %%J% is between 100 and 140)
goto :begin
Output:
117.00 is between 100 and 140
148.00 is greater or equal 140
126.00 is between 100 and 140
96.00 is Less or equal 100
127.00 is between 100 and 140
I have a bat file which simply generates a date
for /f "tokens=2,3,4 delims=/ " %%a in ('date /t') do set CurrYear=%%c
for /f "tokens=2,3,4 delims=/ " %%a in ('date /t') do set CurrMoth=%%a
for /f "tokens=2,3,4 delims=/ " %%a in ('date /t') do set CurrDay=%%b
set bDate =01/%CurrMoth%/%CurrYear%
set eDate=%CurrDay%/%CurrMoth%/%CurrYear%
set /a dayminus = %CurrDay% - 1
echo %dayminus%
pause
The answer I get for echo %dayminus% is 6 instead of 06 & that's my problem.
If your intent is to simply ensure a number is left-zero-padded to two places, you can just use:
if %dayminus% lss 10 set dayminus=0%dayminus%
However, you'll soon run into another problem, specifically what you do when you run this on the first of the month. But that's probably a matter for a separate question (or you could just look at this one).
If you're open to using other tools (which ship with Windows, just like cmd.exe does), then VBScript is possibly the easiest option. You can just create a one-liner yesterdom.vbs:
wscript.echo day(date()-1)
and then call it from your script:
for /f %%a in ('cscript //nologo yesterdom.vbs') do set dayminus=%%a
If you don't want the hassle of maintaining the one-liner, you can create and destroy it from within your script, such as with:
#echo off
echo wscript.echo day(date()-1) >yesterdom.vbs
for /f %%a in ('cscript //nologo yesterdom.vbs') do set dayminus=%%a
del /q yesterdom.vbs >nul: 2>nul:
echo %dayminus%
(Interestingly, most people want to know how to go the other way.) The reason this is happening is because batch considers numbers that begin with a 0 to be octal and then simplifies them to drop the 0 when printing as an integer. You can get around this by treating the variable like a string instead.
set /a dayminus=%CurrDay%-1
if %dayminus% lss 10 (
set dayminus=0%dayminus%
)
echo %dayminus%
Here is a quick workaround that I have prepared for you in a sample program:
#echo off
set /a test = 4
IF %test% lss 10 (
#echo 0%test%
)
#pause
This will always get you a two digit number since anything below 10 will have the added 0 in front of it when it's being written to the screen.
This is a pure Batch file solution that get the date of yesterday; it also works for the current date minus any number of days less than a month:
#echo off
setlocal EnableDelayedExpansion
rem Create array of days per month; both month and day are 100-based
set i=100
for %%a in (31 28 31 30 31 30 31 31 30 31 30 31) do (
set /A i+=1
set "daysPerMonth[!i!]=1%%a"
)
rem Get today's date parts (from "Dow MM/DD/YYYY" format) - 1 day
for /F "tokens=2-4 delims=/ " %%a in ('date /T') do (
set /A MM=1%%a, DD=1%%b-1, YYYY=%%c, YYYYmod4=YYYY %% 4
)
if %YYYYmod4% equ 0 set "daysPerMonth[102]=129"
rem Adjust date if previous month
if %DD% equ 100 (
set /A MM-=1
if !MM! equ 100 (
set /A MM=112, YYYY-=1
)
set /A DD=daysPerMonth[!MM!]
)
set "dateMinus=%DD:~1%/%MM:~1%/%YYYY%
echo %dateMinus%
I'm using a windows command prompt script to read values from different .txt files. First it works, but then later the array seems to be empty.
analyze.bat:
#echo off
setlocal EnableDelayedExpansion
set ID=P8
set comptype=Link
set pattern=(700 710 720 730 740 750 760 770 780 790 )
set n=0
for %%i in %pattern% do (
set j=0
for /f "tokens=1-5" %%a in (.\results\%%i.txt) do (
if %%a==%comptype% if %%b==Results (set t=%%d)
if %%a==%ID% (
set data[%n%][%j%]=%%b
echo !data[%n%][%j%]! <-- This is working
set /a j=!j!+1 )
)
set /a n=!n!+1
)
for /l %%o in (0, 1, %n%) do (
for /l %%k in (0, 1, %j%) do (
echo %data[%%o][%%k]% <-- This is not working
))
The second echo just prints: "ECHO is off.", which leads me to believe that the variable is empty at that point.
Could it have something to do with the delayed expansion of 'data'?
Using ! instead of % for the second echo does not change anything.
EndLocal before or after the last two for-loops also does not help.
try this:
set "data[!n!][!j!]=%%b"
...
...
echo !data[%%o][%%k]!