setlocal EnableDelayedExpansion
set elem[1]=First element
set elem[2]=Second one
set elem[3]=The third one
set i=2
echo !elem[%i%]!
还可以使用 FOR 命令的参数作为索引: for /L %%i in (1,1,3) do echo !elem[%%i]!。你必须使用!索引!当在 FOR 或 IF 中更改索引时,在数组元素中存储值。若要在 FOR/IF 内部的索引发生变化时获取元素的值,请将元素用双百分比符号括起来,并在命令之前加上 call。例如,要将数组元素的范围向左移动四个位置:
for /L %%i in (%start%,1,%end%) do (
set /A j=%%i + 4
call set elem[%%i]=%%elem[!j!]%%
)
实现上述过程的另一种方法是使用一个额外的 FOR 命令,通过一个等效的可替换参数改变索引的延迟展开,然后使用数组元素的延迟展开。此方法运行速度快于前面的 CALL:
for /L %%i in (%start%,1,%end%) do (
set /A j=%%i + 4
for %%j in (!j!) do set elem[%%i]=!elem[%%j]!
)
@echo off
setlocal EnableDelayedExpansion
rem Create vector with names of days
set i=0
for %%d in (Sunday Monday Tuesday Wednesday Thrusday Friday Saturday) do (
set /A i=i+1
set day[!i!]=%%d
)
rem Get current date and calculate DayOfWeek
for /F "tokens=1-3 delims=/" %%a in ("%date%") do (
set /A mm=10%%a %% 100, dd=10%%b %% 100, yy=%%c
)
if %mm% lss 3 set /A mm=mm+12, yy=yy-1
set /A a=yy/100, b=a/4, c=2-a+b, e=36525*(yy+4716)/100, f=306*(mm+1)/10, jdn=c+dd+e+f-1523, dow=jdn %% 7 + 1
echo Today is !day[%dow%]!, %date%
:: Bubblesort
:: Horribly inefficient for large lists
:: Dave Johnson implementation 05/04/2013
@echo off
setlocal enabledelayedexpansion
:: Number of entries to populate and sort
set maxvalue=50
:: Fill a list of vars with Random numbers and print them
for /l %%a in (1,1,%maxvalue%) do (
set /a tosort%%a=!random!
)
:: echo them
set tosort
:: Commence bubble sort
Echo Sorting...
set /a maxvalue-=1
set iterations=0
for /l %%a in (%maxvalue%,-1,1) do ( REM Decrease by 1 the number of checks each time as the top value will always float to the end
set hasswapped=0
for /l %%b in (1,1,%%a) do (
set /a next=%%b+1
set next=tosort!next!
set next=!next!
call :grabvalues tosort%%b !next!
rem echo comparing tosort%%b = !tosortvalue! and !next! = !nextvalue!
if !nextvalue! LSS !tosortvalue! (
rem set /a num_of_swaps+=1
rem echo Swapping !num_of_swaps!
set !next!=!tosortvalue!
set tosort%%b=!nextvalue!
set /a hasswapped+=1
)
)
set /a iterations+=1
if !hasswapped!==0 goto sorted
)
goto:eof
:grabvalues
set tosortvalue=!%1!
set nextvalue=!%2!
goto:eof
:sorted
::nice one our kid
set tosortvalue=
echo Iterations required: %iterations%
set tosort
endlocal
@echo off
rem The subroutines presented bellow implement vectors (arrays) operations in CMD
rem Definition of a vector <v>:
rem v_0 - variable that stores the number of elements of the vector;
rem v_1..v_n, where n=v_0 - variables that store the values of the vector elements.
rem :::MAIN START:::
setlocal disabledelayedexpansion
rem Getting all the parameters passed to the program in the vector 'params':
rem Delayed expansion is left disabled in order not to interpret "!" in the program parameters' values (%1, %2, ... );
rem If a program parameter is not quoted, special characters in it (like "^", "&", "|") get interpreted at program launch.
:loop1
set "param=%~1"
if defined param (
call :VectorAddElementNext params param
shift
goto :loop1
)
rem Printing the vector 'params':
call :VectorPrint params
pause&echo.
rem After the vector variables are set, delayed expansion can be enabled and "!" are not interpreted in the vector variables's values:
echo Printing the elements of the vector 'params':
setlocal enabledelayedexpansion
if defined params_0 (
for /l %%i in (1,1,!params_0!) do (
echo params_%%i="!params_%%i!"
)
)
endlocal
pause&echo.
rem Setting the vector 'filenames' with the list of filenames in the current directory:
rem Delayed expansion is left disabled in order not to interpret "!" in the %%i variable's value;
for %%i in (*) do (
set "current_filename=%%~i"
call :VectorAddElementNext filenames current_filename
)
rem Printing the vector 'filenames':
call :VectorPrint filenames
pause&echo.
rem After the vector variables are set, delayed expansion can be enabled and "!" are not interpreted in the vector variables's values:
echo Printing the elements of the vector 'filenames':
setlocal enabledelayedexpansion
if defined filenames_0 (
for /l %%i in (1,1,!filenames_0!) do (
echo filenames_%%i="!filenames_%%i!"
)
)
endlocal
pause&echo.
endlocal
pause
rem :::MAIN END:::
goto :eof
:VectorAddElementNext
rem Vector Add Element Next
rem adds the string contained in variable %2 in the next element position (vector length + 1) in vector %1
(
setlocal enabledelayedexpansion
set "elem_value=!%2!"
set /a vector_length=%1_0
if not defined %1_0 set /a vector_length=0
set /a vector_length+=1
set elem_name=%1_!vector_length!
)
(
endlocal
set "%elem_name%=%elem_value%"
set %1_0=%vector_length%
goto :eof
)
:VectorAddElementDVNext
rem Vector Add Element Direct Value Next
rem adds the string %2 in the next element position (vector length + 1) in vector %1
(
setlocal enabledelayedexpansion
set "elem_value=%~2"
set /a vector_length=%1_0
if not defined %1_0 set /a vector_length=0
set /a vector_length+=1
set elem_name=%1_!vector_length!
)
(
endlocal
set "%elem_name%=%elem_value%"
set %1_0=%vector_length%
goto :eof
)
:VectorAddElement
rem Vector Add Element
rem adds the string contained in the variable %3 in the position contained in %2 (variable or direct value) in the vector %1
(
setlocal enabledelayedexpansion
set "elem_value=!%3!"
set /a elem_position=%2
set /a vector_length=%1_0
if not defined %1_0 set /a vector_length=0
if !elem_position! geq !vector_length! (
set /a vector_length=elem_position
)
set elem_name=%1_!elem_position!
)
(
endlocal
set "%elem_name%=%elem_value%"
if not "%elem_position%"=="0" set %1_0=%vector_length%
goto :eof
)
:VectorAddElementDV
rem Vector Add Element Direct Value
rem adds the string %3 in the position contained in %2 (variable or direct value) in the vector %1
(
setlocal enabledelayedexpansion
set "elem_value=%~3"
set /a elem_position=%2
set /a vector_length=%1_0
if not defined %1_0 set /a vector_length=0
if !elem_position! geq !vector_length! (
set /a vector_length=elem_position
)
set elem_name=%1_!elem_position!
)
(
endlocal
set "%elem_name%=%elem_value%"
if not "%elem_position%"=="0" set %1_0=%vector_length%
goto :eof
)
:VectorPrint
rem Vector Print
rem Prints all the elements names and values of the vector %1 on sepparate lines
(
setlocal enabledelayedexpansion
set /a vector_length=%1_0
if !vector_length! == 0 (
echo Vector "%1" is empty!
) else (
echo Vector "%1":
for /l %%i in (1,1,!vector_length!) do (
echo [%%i]: "!%1_%%i!"
)
)
)
(
endlocal
goto :eof
)
:VectorDestroy
rem Vector Destroy
rem Empties all the elements values of the vector %1
(
setlocal enabledelayedexpansion
set /a vector_length=%1_0
)
(
endlocal
if not %vector_length% == 0 (
for /l %%i in (1,1,%vector_length%) do (
set "%1_%%i="
)
set "%1_0="
)
goto :eof
)
@echo off
setlocal disabledelayedexpansion
rem Getting all the parameters passed to the program in the array 'params':
rem Delayed expansion is left disabled in order not to interpret "!" in the program parameters' values (%1, %2, ... );
rem If a program parameter is not quoted, special characters in it (like "^", "&", "|") get interpreted at program launch.
set /a count=1
:loop1
set "param=%~1"
if defined param (
set "params_%count%=%param%"
set /a count+=1
shift
goto :loop1
)
set /a params_0=count-1
echo.
rem After the array variables are set, delayed expansion can be enabled and "!" are not interpreted in the array variables's values:
rem Printing the array 'params':
echo Printing the elements of the array 'params':
setlocal enabledelayedexpansion
if defined params_0 (
for /l %%i in (1,1,!params_0!) do (
echo params_%%i="!params_%%i!"
)
)
endlocal
pause&echo.
rem Setting the array 'filenames' with the list of filenames in the current directory:
rem Delayed expansion is left disabled in order not to interpret "!" in the %%i variable's value;
set /a count=0
for %%i in (*) do (
set "current_filename=%%~i"
set /a count+=1
call set "filenames_%%count%%=%%current_filename%%"
)
set /a filenames_0=count
rem After the array variables are set, delayed expansion can be enabled and "!" are not interpreted in the array variables's values:
rem Printing the array 'filenames':
echo Printing the elements of the array 'filenames':
setlocal enabledelayedexpansion
if defined filenames_0 (
for /l %%i in (1,1,!filenames_0!) do (
echo filenames_%%i="!filenames_%%i!"
)
)
endlocal
endlocal
pause
goto :eof
@echo off
set array=
setlocal ENABLEEXTENSIONS ENABLEDELAYEDEXPANSION
set nl=^&echo(
set array=auto blue ^!nl!^
bycicle green ^!nl!^
buggy red
echo convert the String in indexed arrays
set /a index=0
for /F "tokens=1,2,3*" %%a in ( 'echo(!array!' ) do (
echo(vehicle[!index!]=%%a color[!index!]=%%b
set vehicle[!index!]=%%a
set color[!index!]=%%b
set /a index=!index!+1
)
echo use the arrays
echo(%vehicle[1]% %color[1]%
echo oder
set index=1
echo(!vehicle[%index%]! !color[%index%]!
SET "_Arr.Names="Name 1" "Name 2" ... "Name N""
FOR %A IN (%_Arr.Names%) DO @( Echo.%~A )
REM Results:
REM Name 1
REM Name 2
REM ...
REM Name N
下面我们创建了一些哑伪数组和一个手工排序的伪数组,另外还创建了一个有序的伪数组来捕获 DIR 命令的输出。
我们还使用哑伪数组并将其转换为有序数组(之后删除原始哑伪数组变量)。
然后,我们手动更新所有有序数组以包含更多元素。
最后,我们通过对值7到9进行预定义的 For L Loop,并生成一个 Random 值来打印数组的第4个示例值,从而动态地报告 Array 中的一些值。
注:
我创建了一个变量来保存添加成员的方法,从而使添加成员变得更简单。
我指出这一点,因为它应该使我们很容易看到我们如何从有序数组到伪对象的小跳转。
@(
SETLOCAL ENABLEDELAYEDEXPANSION
ECHO OFF
REM Manually Create a shortcut method to add more elements to a specific ordered array
SET "_Arr.Songs.Add=SET /A "_Arr.Songs.0+=1"&&CALL SET "_Arr.Songs.%%_Arr.Songs.0%%"
REM Define some 'dumb' Pseudo arrays
SET "_Arr.Names="Name 1" "Name 2" "Name 3" "Name 4" "Name 5" "Name 6" "Name 7" "Name 8""
SET "_Arr.States="AL" "AK" "AZ" "AR" "CA" "CO" "CT" "DE" "FL" "GA" "HI" "ID" "IL" "IN" "IA" "KS" "KY" "LA" "ME" "MD" "MA" "MI" "MN" "MS" "MO" "MT" "NE" "NV" "NH" "NJ" "NM" "NY" "NC" "ND" "OH" "OK" "OR" "PA" "RI" "SC" "SD" "TN" "TX" "UT" "VT" "VA" "WA" "WV" "WI" "WY""
)
REM Manually Create One Ordered Array
%_Arr.Songs.Add%=Hey Jude"
%_Arr.Songs.Add%=The Bartman"
%_Arr.Songs.Add%=Teenage Dirtbag"
%_Arr.Songs.Add%=Roundabout"
%_Arr.Songs.Add%=The Sound of Silence"
%_Arr.Songs.Add%=Jack and Diane"
%_Arr.Songs.Add%=One Angry Dwarf and 200 Solumn Faces"
REM Turn All Pre-Existing Normal Pseudo Arrays into Element Arrays
REM Since Ordered Arrays use Index 0, we can skip any manually created Ordered Arrays:
FOR /F "Tokens=2 Delims==." %%A IN ('SET _Arr. ^| FIND /V ".0=" ^| SORT') DO (
IF /I "%%~A" NEQ "!_TmpArrName!" (
SET "_TmpArrName=%%~A"
IF NOT DEFINED _Arr.!_TmpArrName!.Add (
REM Create a shortcut method to add more members to the array
SET "_Arr.!_TmpArrName!.Add=SET /A "_Arr.!_TmpArrName!.0+=1"&&CALL SET "_Arr.!_TmpArrName!.%%_Arr.!_TmpArrName!.0%%"
)
FOR %%a IN (!_Arr.%%~A!) DO (
CALL SET /A "_Arr.!_TmpArrName!.0+=1"
CALL SET "_Arr.!_TmpArrName!.%%_Arr.!_TmpArrName!.0%%=%%~a"
)
)
IF DEFINED _Arr.!_TmpArrName! (
REM Remove Unneeded Dumb Psuedo Array "_Arr.!_TmpArrName!"
SET "_Arr.!_TmpArrName!="
)
)
REM Create New Array of unknown Length from Command Output, and Store it as an Ordered Array
SET "_TmpArrName=WinDir"
FOR /F "Tokens=* Delims==." %%A IN ('Dir /B /A:D "C:\Windows"') DO (
IF NOT DEFINED _Arr.!_TmpArrName!.Add (
SET "_Arr.!_TmpArrName!.Add=SET /A "_Arr.!_TmpArrName!.0+=1"&&CALL SET "_Arr.!_TmpArrName!.%%_Arr.!_TmpArrName!.0%%"
)
CALL SET /A "_Arr.!_TmpArrName!.0+=1"
CALL SET "_Arr.!_TmpArrName!.%%_Arr.!_TmpArrName!.0%%=%%~A"
)
)
REM Manually Add additional Elements to the Ordered Arrays:
%_Arr.Names.Add%=Manual Name 1"
%_Arr.Names.Add%=Manual Name 2"
%_Arr.Names.Add%=Manual Name 3"
%_Arr.States.Add%=51st State"
%_Arr.States.Add%=52nd State"
%_Arr.States.Add%=53rd State"
%_Arr.Songs.Add%=Live and Let Die"
%_Arr.Songs.Add%=Baby Shark"
%_Arr.Songs.Add%=Safety Dance"
%_Arr.WinDir.Add%=Fake_Folder 1"
%_Arr.WinDir.Add%=Fake_Folder 2"
%_Arr.WinDir.Add%=Fake_Folder 3"
REM Test Output:
REM Use a For Loop to List Values 7 to 9 of each array and A Psuedo Rnadom 4th value
REM We are only interested in Ordered Arrays, so the .0 works nicely to locate those exclusively.
FOR /F "Tokens=2,4 Delims==." %%A IN ('SET _Arr. ^| FIND ".0=" ^| SORT') DO (
CALL :Get-Rnd %%~B
ECHO.
ECHO.%%~A 7 to 9, Plus !_Rnd#! - Psuedo Randomly Selected
FOR /L %%L IN (7,1,9) DO (
CALL Echo. * Element [%%L] of %%~A Pseudo Array = "%%_Arr.%%~A.%%L%%"
)
CALL Echo. * Random Element [!_Rnd#!] of %%~A Pseudo Array = "%%_Arr.%%~A.!_Rnd#!%%"
)
ENDLOCAL
GOTO :EOF
:Get-Rnd
SET /A "_RandMax=(32767 - ( ( ( 32767 %% %~1 ) + 1 ) %% %~1) )", "_Rnd#=!Random!"
IF /I !_Rnd#! GTR !_RandMax! ( GOTO :Get_Rnd# )
SET /A "_Rnd#%%=%~1"
GOTO :EOF
例子结果:
Results:
Names 7 to 9, Plus 5 - Psuedo Randomly Selected
* Element [7] of Names Pseudo Array = "Name 7"
* Element [8] of Names Pseudo Array = "Name 8"
* Element [9] of Names Pseudo Array = "Manual Name 1"
* Random Element [5] of Names Pseudo Array = "Name 5"
Songs 7 to 9, Plus 5 - Psuedo Randomly Selected
* Element [7] of Songs Pseudo Array = "One Angry Dwarf and 200 Solumn Faces"
* Element [8] of Songs Pseudo Array = "Live and Let Die"
* Element [9] of Songs Pseudo Array = "Baby Shark"
* Random Element [5] of Songs Pseudo Array = "The Sound of Silence"
States 7 to 9, Plus 9 - Psuedo Randomly Selected
* Element [7] of States Pseudo Array = "CT"
* Element [8] of States Pseudo Array = "DE"
* Element [9] of States Pseudo Array = "FL"
* Random Element [9] of States Pseudo Array = "FL"
WinDir 7 to 9, Plus 26 - Psuedo Randomly Selected
* Element [7] of WinDir Pseudo Array = "assembly"
* Element [8] of WinDir Pseudo Array = "AUInstallAgent"
* Element [9] of WinDir Pseudo Array = "Boot"
* Random Element [26] of WinDir Pseudo Array = "Fonts"
(
SETOCAL
ECHO OFF
REM Manage Sites:
SET "Sites=13"
SET "MaxAge=28"
SET "Site.1="[IP]" "[User Name]" "[Password]" "[Path]""
SET "Site.2="[IP]" "[User Name]" "[Password]" "[Path]""
SET "Site.3="[IP]" "[User Name]" "[Password]" "[Path]""
REM ...
SET "Site.11="[IP]" "[User Name]" "[Password]" "[Path]""
SET "Site.12="[IP]" "[User Name]" "[Password]" "[Path]""
SET "Site.13="[IP]" "[User Name]" "[Password]" "[Path]""
)
FOR /L %%L IN (1,1,%Sites%) DO (
FOR /F "Tokens=*" %%A IN ('CALL ECHO %%Site.%%L%%') DO (
Echo. Pulled this example from a more complex example of my actual code, so the example variables may not need this loop, but it won't hurt to have if they don't need the extra expansion.
Call :Log
CALL :DeleteFTP %%~A
)
)
GOTO :EOF
:DeleteFTP
REM Simple ftp command for cygwin to delete the files found older than X days.
SET "FTPCMD="%~dp0lftp" %~1 -u %~2,%~3 -e "rm -rf %~4%MaxAge% "
FOR /F "Tokens=*" %%F IN ('"%FTPCMD% 2^>^&1"') DO @(
ECHO.%%~F
)
GOTO :EOF
@(
SETLOCAL ENABLEDELAYEDEXPANSION
ECHO OFF
SET "_SiteCount=0"
SET "_SiteID=0"
SET /A "_SiteID= !_SiteID! + 1"
SET "Site.!_SiteID!.MaxAge=Day5Ago"
SET "Site.!_SiteID!.Name=[SITE NAME HEADER FOR EMAIL]"
SET "Site.!_SiteID!.Detail="[IP]" "[UserName]" "[Password]" "[Path]""
REM ...
SET /A "_SiteID= !_SiteID! + 1"
SET "Site.!_SiteID!.MaxAge=Day15Ago"
SET "Site.!_SiteID!.Name=[SITE NAME HEADER FOR EMAIL]"
SET "Site.!_SiteID!.Detail="[IP]" "[UserName]" "[Password]" "[Path]""
)
CALL :Main
(
ENDLOCAL
Exit /b %eLvl%
)
:Main
REM In some forms of these the order isn't meaningful, but in others you need to follows the order and so we just count he number of site objects by counting one of their properties.
FOR /F %%A IN ('SET ^| FIND /I "Site." ^| FIND /I ".Name="') DO ( CALL SET /A "_SiteCount+=1" )
FOR /L %%L IN (1,1,34) DO (
CALL :PSGetDate_DaysAgo %%L
)
FOR /L %%L IN (1,1,%_SiteCount%) DO (
SET "Site.%%L.Create=NONE"
)
FOR /L %%L IN (1,1,%_SiteCount%) DO (
FOR /F "Tokens=*" %%A IN ('CALL ECHO ""%%Site.%%L.Name%%" %%Site.%%L.Detail%% "Site.%%L" "%%%%Site.%%L.MaxAge%%%%""') DO (
CALL ECHO CALL :DeleteFTP %%~A
CALL :DeleteFTP %%~A
)
)
CALL :SendMail "%EMLog%" "%_EMSubject%"
GOTO :EOF
:DeleteFTP
REM ECHO.IF "%~7" EQU "%skip%" (
IF "%~7" EQU "%skip%" (
GOTO :EOF
)
SET "FTPCMD="%~dp0lftp" %~2 -u %~3,%~4 -e "rm -rf %~5%~7 "
SET "FTPCMD=%FTPCMD%; bye""
FOR /F "Tokens=*" %%F IN ('"%FTPCMD% 2^>^&1"') DO @(
ECHO."%%F"
ECHO."%%~F"
REM CALL :Output "%Temp%\%~2_%~7.log" "%%F"
%OP% "%Temp%\%~2_%~7.log"
SET "FTPOut=%%~F"
)
GOTO :EOF
SET "_GUID=^%Time^%_^%Random:~-1^%^%Random:~-1^%^%Random:~-1^%^%Random:~-1^%^%Random:~-1^%^%Random:~-1^%^%Random:~-1^%^%Random:~-1^%^%Random:~-1^%"
eg: %~n0.[ObjectName].[Object Property].[Object Sub Property]=[Value, or array of values]
[Script Name]
.[Object Name](May Hold Count of Names)=[int]
.Name=[string]
.Paths(May Hold Count of IDs)=[INT]
.GUID=%_GUID%
.Path=String
.MaxAge=[Int]
.Details=[Array (String)] @(
IP=[SubSting],
Username=[SubString],
Password[SubString])
@(
SETLOCAL ENABLEDELAYEDEXPANSION
ECHO OFF
SET /A "_SiteID= !_SiteID! + 1"
SET "SiteName=SiteA"
SET "%~n0.!SiteName!=%%_SiteID%%
SET "%~n0.!SiteName!.SiteID=!_SiteID!
SET "%~n0.!SiteName!.Paths="PathA" "PathB" "PathC" "PathD" "PathE""
)
CALL :CheckFTP [FTP Login variables from source object including Site ID]
:CheckFTP
REM Not necessary to assign Variables, doing this for exposition only:
CALL SET "TempSiteName=%~6"
CALL SET "TempPaths=%%%~n0.%~1.Paths%%"
REM Clear the site Temp KB variables
FOR \F "Tokens=2* Delims== " %%H IN (%TempPaths% "Total" "Temp") DO (
CALL SET /A "%%%~n0.%~1.Paths.%%~H.KB=0"
)
FOR %%J IN (%TempPaths%) DO (
FOR /F "Tokens=1-2" %%F IN ('[FTP Command using source object options]') DO @(
CALL :SumSite "%~6" "%%~F" "%%~G"
FOR /F "Tokens=1,2,* delims=/" %%f IN ("%%~G") DO (
CALL :ConvertFolder "%~6" "%%~F" "%%~g" "%%~h" "%~6_%%~g_%%~h"
)
)
)
FOR /F "Tokens=3,4,7 Delims==_." %%g IN ('SET ^| FIND /I "%~6_" ^| FIND /I ".KB" ^| FIND /I /V "_."') DO (
CALL :WriteFolder "%%g/%%~h" "%TmpFile%" "%~6_%%~g_%%~h"
REM echo.CALL :WriteFolder "%%g/%%~h" "%TmpFile%" "%~6_%%~g_%%~h"
)
CALL :ConvertSite "%~1"
CALL :WriteTotalFolder "%~7" "%TmpFile%" "%~6"
CALL :SendMail "%TmpFile%" "Backup_%~1"
GOTO :EOF
:SumSite
CALL SET "TSumPaths=%%%~n0.%~1.Paths%% "Total""
FOR %%H IN (%TSumPaths%) DO (
CALL SET /A "%~n0.%~1.Paths.%%~H.KB=%%%~n0.%~1.Paths.%%~H.KB%%+%~2"
)
:SumSite
CALL SET "TSumPaths=%%%~n0.%~1.Paths%% "Total""
FOR %%H IN (%TSumPaths%) DO (
CALL SET /A "%~n0.%~1.Paths.%%~H.KB=%%%~n0.%~1.Paths.%%~H.KB%%+%~2"
)
GOTO :EOF
:ConvertFolder
REM Convert's Folder values to MB and GB
SET /A "%~1.Temp.KB=%~2"
CALL SET /A "%~1.Temp.MB=%%%~1.Temp.KB%%/1024"
CALL SET /A "%~1.Temp.GB=(%%%~1.Temp.KB%%/1024)/1024"
CALL SET /A "%~5.Temp.KB=%%%~5.Temp.KB%%+%~2"
CALL SET /A "%~5.Temp.MB=%%%~5.Temp.KB%%/1024"
CALL SET /A "%~5.Temp.GB=(%%%~5.Temp.KB%%/1024)/1024"
GOTO :EOF
:WriteFolder
CALL :PickGMKBytes "%~1" "%~2" "G" "M" "K" "%%%~3.Temp.GB%%" "%%%~3.Temp.MB%%" "%%%~3.Temp.KB%%"
GOTO :EOF
:PickGMKBytes
IF /I "%~6" NEQ "" (
IF /I "%~6"=="0" (
CALL :PickGMKBytes "%~1" "%~2" "%~4" "%~5" "%~6" "%~7" "%~8"
) ELSE (
CALL :Output "%~2" "%~6%~3 %~1"
)
) ELSE (
CALL :Output "%~2" "0B %~1"
)
GOTO :EOF
:ConvertSite
CALL SET "TempPaths=%%%~n0.%~1.Paths%%"
FOR %%V IN (%TempPaths% "Total") DO (
CALL SET /A "%~1.%%~V.MB=%%%~1.%%~V.KB%%/1024"
CALL SET /A "%~1.%%~V.GB=(%%%~1.%%~V.KB%%/1024)/1024"
)
GOTO :EOF
@ECHO OFF
Set "UseErr=Echo/&Echo/Usage Error - Ensure command extensions and Delayed Expansion are enabled with: &Echo/Setlocal EnableExtensions EnableDelayedExpansion&Echo/ or from the command line:&Echo/CMD /V:On /K&Exit /B 1"
If Not "!Comspec!"=="%Comspec%" (%UseErr%)
(Set "GRPNm="&Set "TAB= "&Set "S_Offset="&Set "mode="&Set "#STDOut="&Set "nGRPNm="&Set "#Order="&Set "#Help="&Set "Inset="&Set "Usage=Echo/###&Exit /B 1") > Nul 2> Nul
(Set "SwParam="&Set "SwFParam="&Set "#ORP#=0"&Set "#FP#=0"&Set "Inset="&Set "#STDOut=0"&Set "GRPNm="&Set "!GRPNm!="&Set "SubEl="&Set "FlNm=%~n0"& Set "Mode="&Set "FindV=") > Nul 2> Nul
If "%~1"=="" (
Echo/&Echo/Modes:&Echo/ [Def]!TAB!!TAB!!TAB!Define, modify or clear an array.
Echo/ [Def]!TAB!!TAB!!TAB!Switches:!TAB![/A:Groupname] [/F:Filepath.ext] [/D] [/O:Index#Arg] [/E:Element Sub value] [[element0] ~ [element#]]
Echo/ [Sort-int]!TAB!!TAB!Sorts array by lowest or highest value using /L or /H switches
Echo/ [Sort-int]!TAB!!TAB!Switches:!TAB![/A:Groupname] [/N:New Groupname] [/L^|/H] [/D]
Echo/ [Sort-str]!TAB!!TAB!Sorts an array or text files string values using alphanumerical order of sort: [0-9][a-z]
Echo/ [Sort-str]!TAB!!TAB!Switches:!TAB![/A:Groupname] [/F:Filepath.ext] [/D]
Echo/ [Find] !TAB!!TAB!Searches an array for the string value supplied.
Echo/ [Find] [searchstring]!TAB!Switches: [/A:Groupname]&Echo/
%Usage:###=/M:Mode required&Echo/[Def][Sort-int^|str][Find-Value]%
) Else Call :GetArgs %*
If Errorlevel 1 Exit /B 1
If "!Mode!"=="" (%Usage:###=/M:Mode required&Echo/[Def][Sort-int^|str][Find-Value]%)
Call :!Mode! %* 2> Nul || (%Usage:###=Invalid Mode or switch error for /M:!Mode!&Echo/[Def][Sort-int^|str][Find-Value]%)
Exit /B 0
:str
Set "Usage=Echo/###&Echo/Call !FlNm! ["/F:filepath.ext" ^| "/A:Array Group Name"] & Exit /B 1"
Set "#!GRPNm!=0"
If "!#FP#!"=="1" (
(For /F "UseBackQ Delims=" %%G in (`Type "!FilePath!" ^| Sort`)Do (
For %%x in ("!GRPNm![!#%GRPNm%!]") Do (
Setlocal DisableDelayedExpansion
Endlocal & Set "%%~x=%%~G"
If "!#STDOut!"=="1" Echo/%%~x=%%~G
)
Set /A "#!GRPNm!+=1"
)) 2> Nul || (%Usage:###:=Echo/Invalid Filepath:"!FilePath!"%)
Exit /B 0
)
If Not "!#FP#!"=="1" (For /F "Tokens=1,2 Delims==" %%G in ('Set !GRPNm![')Do Echo/%%H)>"%TEMP%\__Sort.txt"
(For /F "UseBackQ Delims=" %%G in (`Type "%TEMP%\__Sort.txt" ^| Sort`)Do (
For %%x in ("!GRPNm![!#%GRPNm%!]") Do (
Setlocal DisableDelayedExpansion
Endlocal & Set "%%~x=%%~G"
If "!#STDOut!"=="1" Echo/%%~x=%%~G
)
Set /A "#!GRPNm!+=1"
)
)
Del /Q "%TEMP%\__Sort.txt"
Exit /B 0
:Find
Set "Usage=Echo/###&Echo/Call !FlNm! [/M:Find-Searchstring] [/A:Group Name]&Exit /B 1"
If "!FindV!"=="" (%Usage:###=/M:Find-Value Required%)
(For /F "Tokens=1,2 Delims==" %%i in ('Set !GRPNm![') Do Echo/"%%j"|"%__AppDir__%findstr.exe"/LIC:"!FindV!" > Nul 2> Nul && (Echo/!FindV! found:&Echo/%%~i=%%~j))
Exit /B 0
:Int
Set "Usage=Echo/###&Echo/Call !FlNm! [/M:Sort-Int] [/A:Group Name] [/N:New Group Name] [Sort-Int] [/H^|/L]&Echo/Call %~n0 [/M:Sort-Int] [/A:Groupname] [Sort-Int] [/H^|/L]&Exit /B 1"
If "!#Help!"=="1" (%Usage:###=/M:Sort-Int Usage:%)
If "!nGRPNm!"=="" Set "nGRPNm=!GRPNm!"
If Not "%#Order%"=="" (Call :Sort%#Order% !nGRPNm! #!nGRPNm! !Inset!) Else (%Usage:###=Sort Order Required /H or /L%)
Exit /B 0
::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: Subroutines for Population of Arrays with numeric values in sorted order.
:sortL <Element_VarName> <Element_Index_VarName> <Variable Names containing the values to be Sorted and Populated to the Array>
Set "%2=0"
FOR %%P In (%*) DO If Not "%%P"=="%1" If Not "%%P"=="%2" If Not "%%P"=="" (
Set "%1[!%2!]=!%%P!"
Set /A "%2+=1"
)
For /L %%a In (1,1,!%2!)Do (
Set /A "S_Offset=%%a - 1"
For /L %%b IN (0,1,%%a)Do (
If not %%b==%%a For %%c in (!S_Offset!)Do (
IF !%1[%%c]! LEQ !%1[%%b]! (
Set "tmpV=!%1[%%c]!"
Set "%1[%%c]=!%1[%%b]!"
Set "%1[%%b]=!tmpV!"
))))
Set /A %2-=1
If "!#STDOut!"=="1" For /L %%G in (0 1 !%2!)Do Echo/%1[%%G]=!%1[%%G]!
Exit /B 0
:sortH <Element_VarName> <Element_Index_VarName> <Variable Names containing the values to be Sorted and Populated to the Array>
Set "%2=0"
FOR %%P In (%*) DO If Not "%%~P"=="%~1" If Not "%%~P"=="%2" If Not "%%P"=="" (
Set "%1[!%2!]=!%%~P!"
Set /A "%2+=1"
)
For /L %%a In (1,1,!%2!)Do (
Set /A "S_Offset=%%a - 1"
For /L %%b IN (0,1,%%a)Do (
If not %%b==%%a For %%c in (!S_Offset!)Do (
If Not !%1[%%c]! LSS !%1[%%b]! (
Set "tmpV=!%1[%%c]!"
Set "%1[%%c]=!%1[%%b]!"
Set "%1[%%b]=!tmpV!"
))))
Set /A %2-=1
If "!#STDOut!"=="1" For /L %%G in (0 1 !%2!)Do Echo/%1[%%G]=!%1[%%G]!
Exit /B 0
:Def
Set "Usage=Echo/###&Echo/Call !FlNm! [/M:Def] [/A:Groupname] ["element0" ~ "element#"] [/F:Filepath.ext] [/E:"Element sub value"]&Echo/ - Assign each line in the given filepath plus element parameters to the Array&Echo/Call %~n0 [/M:Def] [/A:Groupname] REM : Clears the Array for the given Group Name&Echo/Call %~n0 [/M:Def] [/A:Groupname] [element] [element] [/O:Index#Arg] REM : Overides Elements from the index supplied&Exit /B 0"
If "!#ORP#!"=="1" Echo/!SwParam!|"%__AppDir__%findstr.exe" /RX [0-9]* > Nul 2> Nul
If not "!SwParam!"=="" If Errorlevel 1 (%Usage:###=O:!SwParam! #Arg invalid. Only Integers accepted.%)
If "!GRPNm!"=="" (%Usage:###=/A:Groupname Required%)
If "!#ORP#!"=="1" Set "#!GRPNm!=0"
If "!#%GRPNm%!"=="" Set "#!GRPNm!=0"
If "%#FP#%"=="1" (
If exist "!FilePath!" (
For /F "Delims=" %%G in (!FilePath!)Do If Not "%%~G"=="" (
For %%x in ("!GRPNm![!#%GRPNm%!]")Do (
Setlocal DisableDelayedExpansion
If "%#STDOut%"=="1" Echo/%%~x=%%~G
Endlocal & Set "%%~x=%%G"
)
Set /A "#!GRPNm!+=1" > Nul
)
) Else (%Usage:###=/F:!FilePath! Invalid path%)
)
If not "!Inset!"=="" (
For %%G in (!Inset!)Do (
For %%x in ("%GRPNm%[!#%GRPNm%!]")Do (
Setlocal DisableDelayedExpansion
If "%#STDOut%"=="1" Echo/%%~x=%%~G
Endlocal & Set "%%~x=%%~G"
)
If Not "!SubEL!"=="" Set "%%~G=!SubEl!"
Set /A "#!GRPNm!+=1" > Nul
)
) Else (
If Not "%#FP#%"=="1" (
For /F "Tokens=1,2 Delims==" %%I in ('Set %GRPNm%')Do Set "%%~I=" > Nul 2> Nul
Set "#!GRPNm!=" > Nul 2> Nul
)
)
Exit /B 0
:GetArgs
If Not "!#Help!"=="1" If "%~1" == "" (
If /I "!Mode!"=="int" If "!GRPNm!"=="" (Echo/Call %~n0 [/M:Sort-int] [/A:GroupName] [/H^|/L] [/D]&%Usage:###=/A:Groupname Required%)Else If /I "!Mode!"=="int" (For /F "Tokens=1,2 Delims==" %%G in ('Set !GRPNm![')Do Set "Inset=!Inset! %%G") > Nul 2> Nul || (%Usage:###=Usage Error - /A:!GRPNm! is not defined%)
If /I "!Mode!"=="str" If "!GRPNm!"=="" (Echo/Call %~n0 [/M:Sort-str] [/A:GroupName] [/N:New Groupname] [/F:Filepath.ext] [/D]&%Usage:###=/A:Groupname Required%)Else If /I "!Mode!"=="str" (For /F "Tokens=1,2 Delims==" %%G in ('Set !GRPNm![')Do Set "Inset=!Inset! %%G") > Nul 2> Nul || (%Usage:###=Usage Error - /A:!GRPNm! is not defined%)
Exit /B 0
) Else If "%~1" == "" Exit /B 0
Set "Param=%~1"
Echo/"!Param!"|"%__AppDir__%findstr.exe" /LIC:"Find-" > Nul 2> Nul && ((Set "FindV=!Param:/M:Find-=!"&Set "Mode=Find")&Shift&Goto :GetArgs)
Echo/"!Param!"|"%__AppDir__%findstr.exe" /LIC:"/M:" > Nul 2> Nul && (
Set "MODE=!Param:*/M:=!"& Echo/"!Mode!"|"%__AppDir__%findstr.exe" /LIC:"Sort-" > Nul 2> Nul && (Set "Mode=!Mode:*Sort-=!")
If "!Param:*/M:=!"=="" (
Echo/&Echo/Modes:&Echo/ [Def]!TAB!!TAB!Define, modify or clear an array.
Echo/ [Sort-int]!TAB!Sorts array by lowest or highest value using /L or /H switches
Echo/ [Sort-str]!TAB!Sorts an array or text files string values using alphanumerical order of sort: [0-9][a-z]
Echo/ [Find:Value]!TAB!Searches an array for the string value supplied.&Echo/
%Usage:###=/M:Mode required&Echo/[Def][Sort-int^|str][Find-Value]%
)
Shift&Goto :GetArgs
)
Echo/"%~1"|"%__AppDir__%findstr.exe" /LIC:"/H" > Nul 2> Nul && (Set "#Order=H"&Shift&Goto :GetArgs)
Echo/"%~1"|"%__AppDir__%findstr.exe" /LIC:"/L" > Nul 2> Nul && (Set "#Order=L"&Shift&Goto :GetArgs)
Echo/"%~1"|"%__AppDir__%findstr.exe" /LIC:"/D" > Nul 2> Nul && (Set "#STDOut=1"&Shift&Goto :GetArgs)
Echo/"%~1"|"%__AppDir__%findstr.exe" /LIC:"/F:" > Nul 2> Nul && ((If Not "!Param:/F:=!"=="" (Set "#FP#=1"&Set "FilePath=!Param:/F:=!")Else %Usage:###=/F:Filepath.ext not Supplied%)&Shift&Goto :GetArgs)
Echo/"%~1"|"%__AppDir__%findstr.exe" /LIC:"/N:" > Nul 2> Nul && (Set "nGRPNm=!Param:*/N:=!"&(If "!Param:*/N:=!"=="" %Usage:###=/N:New Group Name required%)&Shift&Goto :GetArgs)
Echo/"%~1"|"%__AppDir__%findstr.exe" /LIC:"/A:" > Nul 2> Nul && (Set "GRPNm=!Param:*/A:=!"&(If "!Param:*/A:=!"=="" %Usage:###=/A:Group Name required%)&Shift&Goto :GetArgs)
Echo/"%~1"|"%__AppDir__%findstr.exe" /LIC:"/O:" > Nul 2> Nul && (Set "SwParam=!Param:*/O:=!"&(If Not "!Param:/O:=!"=="" (Set "#ORP#=1")Else %Usage:###=/O:#Arg not Supplied%)&Shift&Goto :GetArgs)
Echo/"%~1"|"%__AppDir__%findstr.exe" /LIC:"/E:" > Nul 2> Nul && (Set "SubEl=!Param:*/E:=!"&(If "!Param:/S:=!"=="" %Usage:###=/E:Sub Element not Supplied%)&Shift&Goto :GetArgs)
Set Inset=!Inset! %1
Shift&Goto :GetArgs