0

Good Day, I here a batch script that uses a function to operate

@echo off
setlocal enableDelayedExpansion
:INSTALLER

    
set "n1=7_Zip"
set "n2=Adobe_Products"
set "n3=Allavsoft"
set "n4=Astute_Graphics"
set "n5=AutoHotkey"
set "n6=Backup_and_Sync_from_Google"
set "n7=BlueStacks_5_Beta"
set "n8=CC_Cleaner"
set "n9=Core_Temp"
set "n10=CPUID_CPU-Z"
  

I'm having trouble because I want the variable n1 n2...10 to be dependent, Meaning I want it to be like this !n%c%! (where %c%is the number after n) so when I insert a new program between 2 programs the numbering will be moved. For example, I will insert the Notepad++ between CC_cleaner and Core_Temp. Now when I insert the Notepad++ its number will be the Old number of Core_Temp which is 9 and the New number of Core_Temp will be 10 and the New number of the CPUID_CPU-Z will be 11. I just can't figure out where I can get the variable 1 2 ... 11 to be substituted to the value of %c%. I'm thinking of a for loop that will count from 1 to 50 and set each number as a variable so I can Substitute those variables for the value of %c% but I don't know how to make it.

I'm also open to other options aside from for loop

Eliazar
  • 301
  • 3
  • 13
  • Does this answer your question? [Arrays, linked lists and other data structures in cmd.exe (batch) script](https://stackoverflow.com/questions/10166386/arrays-linked-lists-and-other-data-structures-in-cmd-exe-batch-script) – Squashman May 26 '21 at 02:43
  • @Squashman - I can't see any answer that can help me in that question, can you please guide me what specific answer is it? – Eliazar May 26 '21 at 07:26
  • I suggest you read through the answer with the most votes. As it is the answer we lead everyone to when they have a question about arrays. It does a very good job of explaining how to do it in a batch-file – Squashman May 26 '21 at 13:29
  • Thank you, I will surely look forward in looking for that – Eliazar May 26 '21 at 13:37

1 Answers1

0

use a function to define the array. In doing so, new values only need to be added to the list of parameter values the function is called with.

Edit: I'm not sure whats unclear given the usage example provided and the description of the argument structure of the function, so heres a desciption of the functionality of the function:

In your opening question, you manually define an array with the prefix n followed by numeric indexes one at a time:

set "n1=7_Zip"
set "n2=Adobe_Products"
set "n3=Allavsoft"
set "n4=Astute_Graphics"
set "n5=AutoHotkey"
set "n6=Backup_and_Sync_from_Google"
set "n7=BlueStacks_5_Beta"
set "n8=CC_Cleaner"
set "n9=Core_Temp"
set "n10=CPUID_CPU-Z"

The above method of hard coding each value to an index makes adding values to the beginning / middle of the array time consuming as each n# has to be manually updated.

Rather than hardcoding each value line by line, The function below takes a list (or series of lists) as parameters containing the arrays name (%1, the first argument) and the values to be defined to the array (all other arguments), assigns the list to a variable in order to seperate the array name from the values to be defined, then uses a For loop to iterate over the values, increment the arrays unique index, and then assigns the current value in the list to the appropriate index.

This allows the above definitions to be achieved using the following call:

Call :DefineArray n 7_Zip Adobe_Products Allavsoft Astute_Graphics AutoHotkey Backup_and_Sync_from_Google BlueStacks_5_Beta CC_Cleaner Core_Temp CPUID_CPU-Z

Example output (with Set n.):

n.1=7_Zip
n.10=CPUID_CPU-Z
n.2=Adobe_Products
n.3=Allavsoft
n.4=Astute_Graphics
n.5=AutoHotkey
n.6=Backup_and_Sync_from_Google
n.7=BlueStacks_5_Beta
n.8=CC_Cleaner
n.9=Core_Temp

Notes:

  • The function defines array variables using an additional . suffix to the arrays prefix name (IE: n.1 n.2 ...). This is done to allow differentiation of the array from other environment variables that begin with the same prefix as the arrays variable name when the Set command is being used.
  • The function does not zero the index count of the array when called. This allows calls to define values to be spread over multiple lines for easier maintenance and readablity.
@Echo off

:# prepare envarinoment for use of '!' expansion during code blocks
:# '!' expansion allows access of variables whose name contains other variables
:#     and provides protection against batch poison characters
 Setlocal EnableExtensions EnableDelayedExpansion

:# Calls the label DefineArray with parameters; doublequoting any string containing
:#     standard delimiters
 Call :DefineArray arrayname value1 "value 2"

:# Display defined variables prefixed with arrayname
 Set arrayname
Goto :Eof

:# Function label name and arg structure
:DefineArray groupname list of values

:# Define all paramters to Params with leading whitespace used to remove groupname from parameter list.
 Set ^"Params= %*"

:# Remove the groupname from the list of elements to be assigned
 Set "Params=!Params: %1 =!"

:# Initialise array index variable specific to the groupname;
:#     [If not already incremented]

 Set /A "%~1[i]+=0"

:# iterate over Params list; increment group index count; Assign element
:# to groupname.index
 For %%G in (!Params!)Do (
  Set /A "%~1[i]+=1"
  Set "%~1.!%~1[i]!=%%~G"
 )

:# exit function
 Exit /b 0

Note: The method used above will consume any ! characters present in values due to Delayed expansion.

T3RR0R
  • 2,747
  • 3
  • 10
  • 25
  • Thank you for your answer, can you explain it in a more specific way. I don't understand the this part of the script `@Echo off Setlocal EnableExtensions EnableDelayedExpansion Call :DefineArray arrayname value1 "value 2" Set arrayname Goto :Eof :DefineArray groupname list of values :# leading whitespace used to remove groupname from parameter list. Set ^"Params= %*" Set "Params=!Params: %1 =!"` – Eliazar May 26 '21 at 02:11
  • I'm practicing batch files for at least 2 weeks now, and I manage to understand some of the scripts. – Eliazar May 26 '21 at 02:13
  • Answer updated with additional remarks to explain each step. For more information about each command, open `cmd.exe` and type: `commandname /?` or visit [ss64](https://ss64.com/nt/) and view the link/s for the command you wish to learn. ss64 contains additional usage examples and information for most commands. – T3RR0R May 26 '21 at 03:15
  • Thank you so much, Also if it's okay, what resources/books can I read to be better in batch files? – Eliazar May 26 '21 at 03:29
  • There's a built-in `help` command, and if the command window is too small for reading there to be useful, all of the same information is also on ss64.com. – SomethingDark May 26 '21 at 03:48
  • @SomethingDark - Thank you for the suggestion. I will try it. – Eliazar May 26 '21 at 05:03
  • @T3RR0R - Thank you for the answer, Now, I'm just having a hard time understanding about what is the purpose of the `groupname` and `arrayname`. Can you tell me what is it? – Eliazar May 26 '21 at 06:01
  • @T3RR0R - Also is the groupname and arrayname necessary or it is just optional? Also what is `%%~G`? – Eliazar May 26 '21 at 09:18
  • Arrayname is the prefix of the variable, in addition to.indexnumber. it is the first parameter the function is called with and allows multiple arrays to be defined using the same function. It is entirely your choice as to what naming convention you use in place of arrayname. – T3RR0R May 26 '21 at 09:23
  • `%%~G` is the value of the for loop variable currently being iterated through in the for set - `(!Params!)`. The tilde - `~` acts to remove outer DoubleQuotes from the value if present. – T3RR0R May 26 '21 at 09:26
  • @T3RR0R - Oh, now I get it. But earlier I've tried to change the `Call :DefineArray arrayname value1 "value 2"` to `Call :DefineArray arrayname %n1% %n2%` for me to test it, I also add a pause to the end before the `:# exit function`. Now, After I run the batch script, It didn't change the order of the `Notepad++ between CC_cleaner and Core_Temp`. Just asking. because now I realized the structure of your script but I can't find the place where I can place it, I'm just curious, what will this batch script do? and also what specific thing that this batch script will do? – Eliazar May 26 '21 at 10:00
  • @T3RR0R - Also, I can't figure out what specific thing does this function do? All seems working right, I'm just not sure how this function can change the order of the list? – Eliazar May 26 '21 at 12:58
  • the order is changed by changing the position of values in the parameter list when calling the function. See the updated answer for a detailed explanation of the functionality of the function. – T3RR0R May 26 '21 at 14:32
  • Ahhhh, Now I understand it. Thank you for your very helpful answer. – Eliazar May 26 '21 at 22:13