2

I have an array in a batch file which contains several file directories. I would like to remove the first three elements of the array and have everything shift over (i.e. the fourth element takes the place of the first, the fifth element takes the place of the second, sixth takes the place of the third, etc). Is this something that can be done in a Batch script?

Example:

[directoryA, directoryB, directoryC, directoryD, directoryE, directoryF]

is changed to:

[directoryD, directoryE, directoryF]

Here is the code I have for the "array":

set paramCount=0
for %%x in (%*) do (
  set /A paramCount+=1
  set "dirs[!paramCount!]=%%x"
)
DerStrom8
  • 1,311
  • 2
  • 23
  • 45
  • which batch script shell is this? DOS/WINDOWS? – Preet Sangha Nov 14 '13 at 23:37
  • Oops, sorry--forgot to mention that. I'm writing a basic Windows .bat file. I'm just starting with batch scripts so I'm not sure if that is the answer you're looking for. – DerStrom8 Nov 14 '13 at 23:42
  • What version of Windows are you running? Windows 7? 8? ME? – Taylor Hx Nov 15 '13 at 00:03
  • This machine is Windows 8, though if possible I'd like to run it on my 7 machine as well – DerStrom8 Nov 15 '13 at 00:04
  • You can't really remove elements from an array, in batch or any other language. Arrays map to blocks of memory, you can NULL an element, but you cannot remove its index. – Taylor Hx Nov 15 '13 at 00:09
  • 1
    Please give us some example of the code you have already and we can provide better advice. – Mark Nov 15 '13 at 00:10
  • This also does not even go into the fact that batch doesn't actually support arrays, it only gives the impression that you are working with arrays. See here: http://stackoverflow.com/a/10167990/2081889 – Taylor Hx Nov 15 '13 at 00:11
  • 1
    Is your array stored in a single variable with comma-delimiters or is it in many variables? Do the directorynames contain quotes or non-alphameric characters? – Magoo Nov 15 '13 at 00:13
  • Thanks guys, code snippet has been added. I would like to remove the first three elements of "dirs" if possible. Cheers. – DerStrom8 Nov 15 '13 at 01:28
  • The array contains several "string" depicting the directories. For example: C:\Users\user\Documents So yes, it does contain non-alphanumeric characters. – DerStrom8 Nov 15 '13 at 01:36
  • 1
    I'm not sure if anyone is following the comments on the answer, but I'd just like to mention that I ended up setting the elements I didn't want to null, then used a for loop to add all non-null values to a second array. This seemed to work. Thanks guys! – DerStrom8 Nov 15 '13 at 02:02

2 Answers2

3

The best was I can think of to do this is to have two "arrays", one for the data, another for whether the data is currently valid. The sample code below creates one dirs "array" holding any command line parameters and another valid "array" and then prints only "valid" data from dirs.

valid[i] will be equal to 1 if and only if the data in dirs[i] is valid. Any other value in valid[i] will indicate that the data in dirs[i] is to be ignored.

@echo off
setlocal enabledelayedexpansion

set paramCount=0
for %%x in (%*) do (
  echo %%x
  set /A paramCount+=1

  REM Add data to dirs array
  set "dirs[!paramCount!]=%%x"

  REM Add valid flag to valid array
  set "valid[!paramCount!]=1"
)

echo Printing...

REM Delete element at index 2
set valid[2]=0

REM Print the modified array
for /L %%a in (1 1 %paramCount%) do (
  IF !valid[%%a]!==1 (echo !dirs[%%a]!)
)

Example Output:

$>deletetest.bat 1 2 3 4
1
2
3
4
Printing...
1
3
4
Taylor Hx
  • 2,815
  • 23
  • 36
  • Very interesting idea. I hadn't thought of doing it that way. What I ended up doing was to set the first three elements to null, and then create another "array" by using a for loop. The for loop would go through the dirs, check if their value is null, and if it's not then it would add it to the new "array". I then used the new array for reference. Thanks everyone for the help! – DerStrom8 Nov 15 '13 at 02:01
  • This same method occurred to me, but it's a little more verbose than the method above (requiring a full rebuild of the array after any modification) whereas the solution above allows you to optionally rebuild at any time. – Taylor Hx Nov 15 '13 at 02:16
  • You have a very good point there. Right now I'm just trying to get it to work, and eventually I'll be doing the fine-tuning and clean-up. I may switch out the more verbose code segments when the time comes, and you've been a great help. I'll use this as the accepted answer and will probably implement it later. – DerStrom8 Nov 15 '13 at 03:00
2

Excuse me. I would like to state some aclarations about this topic.

You have not indicated where your "array" come from. You may store it in a variable, for example:

set dirs=directoryA directoryB directoryC directoryD directoryE directoryF

However, this is not an array, but a list. You may create this list from the parameters of a subroutine this way:

set dirs=%*

If you want to remove the first three elements from this list, you may do that this way:

for /F "tokens=3*" %%a in ("%dirs%") do set dirs=%%b

Another possibility is that the directories were passed to a subroutine as a parameters list:

call :subroutine directoryA directoryB directoryC directoryD directoryE directoryF

I think this is the case based on your example. In this case it is very easy to "remove" the first three parameters via three shift commands:

:subroutine
rem Remove first three parameters:
shift
shift
shift
rem Process the rest of parameters:
:nextParam
   if "%1" equ "" goto endParams
   echo Next param is: %1
   shift
goto nextParam
:endParams

However, if you have a "real" array (with numeric subscripts that start at 1) that may also be created from the parameters list for a subroutine this way (like in your example):

set paramCount=0
for %%x in (%*) do (
   set /A paramCount+=1
   set "dirs[!paramCount!]=%%x"
)

Then you may remove the first three elements this way:

for /L %%i in (4,1,%paramCount%) do (
   set /A j=%%i-3
   set dirs[!j!]=!dirs[%%i]!
)
set /A paramCount-=3
Aacini
  • 65,180
  • 12
  • 72
  • 108
  • This post was very informative, thank you. I should have gone a bit further back. I am calling this batch file from my java program. I pass in a number of strings as parameters using the "commands[]" array offered by the Java API for the Runtime.getRuntime().exec() method. Each directory is passed in as a parameter. I then access these parameters and use them to set local variables, which I can operate on later in the script. I hope this clears up some things. – DerStrom8 Nov 15 '13 at 13:24