Arrays, linked lists, and other data structures in cmd.exe (package) script

I played with cmd.exe, but in its help I did not find any information on how to define arrays.

I found how to define simple variables:

set a=10 echo %a% 

But I want to create arrays, linked list, etc ...

So, can it in cmd.exe (I mean: is there any array keywords in cmd.exe?)

I want to implement some algorithms like:

  • bubble sort
  • quick sort
  • sorting gnomes

etc...

So, I also want to know if there are links or instances, structures, etc. in Cmd.exe?

Because his help is not complete in: /?

Can Cmd.exe be defined as complete by the definition of a Turing machine? (Turing Complete)

+57
arrays windows scripting shell cmd batch-file delayedvariableexpansion
Apr 15 2018-12-12T00:
source share
9 answers

Ok I will try to be as clear as possible so that you are not understood ...

In Windows batch files, the variable name must begin with a letter and may contain any valid character, where the valid characters are: # $ '() * +, -.? @ [] _ ​​`{} ~ Except letters and numbers.

This means that in terms of cmd.exe, SET NORMAL_NAME=123 exactly matches SET A#$'()*+,-.?@[\]_{}~=123 and also matches SET VECTOR[1]=123 ; all three are normal variables. Thus, you will have to write the variable names as array elements:

 set elem[1]=First element set elem[2]=Second one set elem[3]=The third one 

Thus, echo %elem[2]% display Second one .

If you want to use another variable as an index, you should know that replacing variables enclosed in percentage of characters by their values ​​is analyzed from left to right; it means that:

 set i=2 echo %elem[%i%]% 

does not give the desired result, because it means: shows the value of the variable elem[ , followed by i , followed by the value of the variable ] .

To solve this problem, you should use Delayed Expansion, that is, insert the setlocal EnableDelayedExpansion at the beginning, enclose the percent indices and enclose the array elements in exclamation points:

 setlocal EnableDelayedExpansion set elem[1]=First element set elem[2]=Second one set elem[3]=The third one set i=2 echo !elem[%i%]! 

You can also use FOR command parameters as indices: for /L %%i in (1,1,3) do echo !elem[%%i]! . You must use! Index! to store values ​​in array elements when the index changes inside FOR or IF: set elem[!index!]=New value . To get the value of an element when the index changes inside FOR / IF, enclose the element in double percent characters before the call command. For example, to move a range of array elements to four places on the left:

 for /L %%i in (%start%,1,%end%) do ( set /A j=%%i + 4 call set elem[%%i]=%%elem[!j!]%% ) 

Another way to achieve the previous process is to use an additional FOR command to change the delayed index expansion with an equivalent plug-in parameter, and then use the delayed extension for the array element. This method works faster than the previous CALL:

 for /L %%i in (%start%,1,%end%) do ( set /A j=%%i + 4 for %%j in (!j!) do set elem[%%i]=!elem[%%j]! ) 

Thus, the batch file behaves as if it were managing arrays. I think the important point here is not a discussion of whether Batch manages arrays or not, but the fact that you can manage arrays in batch files in an equivalent way to other programming languages.

 @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% 

Note that index values ​​are not limited to numbers, but they can be any string containing valid characters; this point allows you to determine what is called associative arrays in other programming languages. This answer provides a detailed explanation of the method used to solve the problem using an associative array. Also note that space is a valid character in variable names, so you should pay attention not to insert spaces in variable names that might go unnoticed.

I elaborated on the reasons why I should use an array entry in batch files in this post .

In this post there is a batch file that reads a text file and stores the row indices in a vector, and then makes the Buble Types of vector elements based on the contents of the string; the equivalent result is sorting the contents of the file.

In this post, there is a basic application for a relational database in batch mode based on indexes stored in files.

This post in Batch has a complete few applications with a linked list that collects a large data structure taken from a subdirectory and displays it in the form of the TREE command.

+151
Apr 16 '12 at 2:15
source share

Windows shell scripts are really not designed to work with arrays, not to mention complex data structures. For the most part, all the lines are in the Windows shell, but there are some things you can do to "work" with arrays, for example declaring n variables VAR_1, VAR_2, VAR_3... using a loop and filtering on the VAR_ prefix, or creating a separator strings, and then using the FOR construct, which iterates over the separator string.

Similarly, you can use the same basic idea to create a structural set of variables like ITEM_NAME, ITEM_DATA or w / e. I even found this link that talks about modeling an associative array in CMD.

All this is terribly hacky and uncomfortable when it comes to it. The command line was simply not designed for intensive programming. I agree with @MatteoItalia - if you need serious scripting, use a real scripting language.

+7
Apr 15 '12 at 10:01
source share

Seriously: I never heard that the party has arrays, maybe you can imitate them with some strange trick, but I would not call it a good idea.

Links / instances / structures are material for the real language, cmd scripts are just a bunch of extensions that grew over the most primitive interpreter that was command.com, you can do some basic scripts, but something more complex than a bunch Calling other teams is doomed to become ugly and incomprehensible.

The only "advanced" construct is the do-it-all weirdo for loop, which, mixed with the strange "rules" for changing variables ( %var% , %%var ,! !var! ), Are two different things due to the idiotic parser) , makes even trivial algorithms a collection of strange hacks (see, for example, here for the quicksort implementation ).

My advice: if you want to make your script in a reasonable way, use the real scripting language and leave the package for simple, fast hacks and for backward compatibility.

+6
Apr 15 2018-12-12T00:
source share

I did an implementation of sorting bubbles in batch using pseudo-arrays some time ago. Not sure why you are using it (although I agree to do it in another batch file), as it becomes rather slow as the size of the list increases. It was more in order to pose a small challenge. Someone may find this helpful.

 :: 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 
+6
Mar 05 '14 at 10:14
source share

Regarding this statement:

I found how to define simple variables:

 set a = 10 echo %a% 

This is simply wrong! Variable a will remain empty (suppose that it was empty initially) and echo %a% will return ECHO is on. A variable named a SPACE will actually be set to SPACE 10 .

So for the code to work, you have to get rid of SPACEs around the equal sign:

 set a=10 echo %a% 

To make the assignment safe for all characters, use the quoted syntax (suppose you have activated command extensions , which is used by default on the Windows command line):

 set "a=1&0" echo(%a% 

For the rest of your question, I recommend reading Aacini's excellent and comprehensive answer .

+4
Mar 17 '17 at 15:18
source share

The following program simulates the operation of vectors (arrays) in cmd . The subroutines presented in it were originally intended for some special cases, such as storing program parameters in an array or looping through file names in a " for " loop and storing them in an array. In these cases, in the enabled delayed expansion block, the characters β€œ ! ”, If they are present in the parameter values ​​or in the value of the β€œ for ” loop variable, will be interpreted. Therefore, in these cases, routines should be used inside the disabled delayed expansion block:

 @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 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 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 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 ) 

It is also possible to save the program parameters in an "array" or encode the file names in a directory using the " for " loop and save them in the "array" (without interpreting " ! " Into their values) without using the presented routines in the program above:

 @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 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 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 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 
+2
Jan 21 '16 at 10:29
source share

TL; DR:

I came across the idea of ​​using a "For" loop and a "set" command to allow parsing of variables, which allowed me to create pseudo-arrays in both an ordered style and a linked list style, and, more importantly, pseudo-objects, akin to structures .

Typical Pseudo Array batch and how to analyze it:

 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 

Below we will make some Dumb Pseudo Arrays and manually ordered Pseudo Array, and also create an Ordered Pseudo Array that intercepts the output of the DIR command.

We also take Dumb Pseudo Arrays and convert them to Ordered (after removing the original Dumb Pseudo Array variables).

Then we update all ordered arrays so that they contain more elements manually.

Finally, we dynamically report some values ​​from the array by executing a predefined For L loop for values ​​from 7 to 9 and generating a random value to print the 4th example of the array value.

Remarks:

I am creating a variable to hold the method for adding members to make it easier to add.

I emphasize this, as this should facilitate understanding of how we make a minor transition from ordered arrays to pseudo objects.

 @( 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 

Example Results:

 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" 



Initially, I would do something similar to Aacini, a simple string of variables with an incremental counter, manually or assigning them using a simple loop from a quick list of variables.

This was good for small 2-D arrays.

However, I find this a pain for long data arrays, especially when I need multi-valued content.

Not to mention when I need to dynamically map and populate content in these multidimensional arrays where simple use is violated there.

I found that it became difficult when you needed several arrays of information that you needed to update or add functions in all directions.

- , , , , .

, , , FTP-, X .

, :

 Site.##=[Array (String)] [Array (String)] @( IP=[SubSting], Username=[SubString], Password[SubString]) 

.

 ( 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 

, 13 , , , . ? , .

, 5, .

 ::... SET "Site.1="[IP]" "[User Name]" "[Password]" "[Path]" "[Site Name]"" ::... 

, ( IP-, , ), 13 , .

 ::... SET "Site.1="[Site Name]" "[IP]" "[User Name]" "[Password]" "[Path]"" ::... FOR /F "Tokens=*" %%A IN ('CALL ECHO %%Site.%%L%%') ::... SET "FTPCMD="%~dp0lftp" %~2 -u %~3,%~4 -e "rm -rf %~5%MaxAge% " ::... 

:

  • , , , .
  • , , , .
  • 30, 40, 50 , , , , ..

  • , , , , , .

  • , / , , .

, , , .

? , :

, () cmd, .

IE " ", , . CMD -, , .

, , , , , :

 eg: Site.[ID].[Object Property]=[Value, or array of values] Site .ID=[int] .Name=[string] .Path=[String] .MaxAge=[Int] .Details=[Array (String)] @( IP=[SubSting], Username=[SubString], Password[SubString]) 

, , , , , .

:

 @( 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]) 

, , , , , .

, , , .

, FTP, , :

 @( 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 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 

, , , , , , : , , , , , .. .

, , , , . , .

0
14 . '18 20:10
source share

Windows , , . , , , , , - . , . , .

-one
15 . '12 22:03
source share
 @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%]! 
-3
02 . '16 10:21
source share



All Articles