0

I'm new to bat scripting and I wanted to use an iterative loop in my script (something like this in javascript for example)

for(var i=0;i<n;i++){ 
    //my code here
    console.log("my tab ["+i+"] is:"+tab[i];
}

So, basicaly this is my bat script in a file called exctract_excel_info.bat:

@ECHO OFF
::setlocal enabledelayedexpansion
:start
ECHO "Hi it's MIBE in this script i will list all the files with the extention xlsx or xls">log.txt
:start_loop
echo Listing all files in the current directory %cd% >log.txt
ECHO ==================  ======================>>log.txt

set "AllowExt= *.xls"
ECHO the variable AllowExt in the first instruction %AllowExt%>>log.txt

set theFileName="NONE"
set /a i = 0
  for %%a in (%AllowExt%) do (
    set /a i = i + 1
    ::echo Found the file: "%%a">>log.txt
    set theFileName[%i%]=%%a
  )
:end_loop
ECHO ============================================>>log.txt
ECHO "The value of i is %i%">>log.txt
ECHO ============================================>>log.txt
   for /L %%x in (1,1,%i%) do (
       ECHO found the file %theFileName[%%x]%>>log.txt
   )
ECHO ============================================>>log.txt
timeout /t 2
ECHO Yo the file %theFileName[0]% will be passed as a parameter
ECHO  The array of files %theFileName%>>log.txt
:run_node
node main.js "%theFileName[0]%">>log.txt
timeout /t 2
:end
::PAUSE

I have a problem reading the value of the variable theFileName[i] in line 32

       ECHO found the file %theFileName[%%x]%>>log.txt

This is the output (log.txt):

Listing all files in the current directory C:\Users\mibe\my bat
==================  ======================
the variable AllowExt in the first instruction  *.xls
============================================
"The value of i is 4"
============================================

So my problem is what is the proper way to read the value of the items inside theFileName array?

PS: when I comment the lines 31, 32, and 33:

   for /L %%it in (1,1,"%i%") do (
       ECHO found the file %theFileName[%%it]%>>log.txt
   )

the script executes properly and get the value of %theFileName[0]%

  • why did you quote `%i%` in line 31? Also `for` metavariables are one-letter only. `%%it` doesn't work. – Stephan Dec 28 '20 at 09:46
  • `%i%` in line 25 needs [delayed expansion](https://stackoverflow.com/questions/30282784/variables-are-not-behaving-as-expected/30284028#30284028) – Stephan Dec 28 '20 at 09:49
  • Thanks for your comment i have changed the variable name `%%it` to `%%x` in line 31 – Mohamed ISMAIL Dec 28 '20 at 11:09
  • don't forget to change it in line 32 too. – Stephan Dec 28 '20 at 11:16
  • So if get it right the line 32 should be something like this: `ECHO found the file %theFileName[!x!]%>>log.txt ` – Mohamed ISMAIL Dec 28 '20 at 11:41
  • I would like to mention that i didn't know how to use the delayed expansion in my script In the line 25 i changed my code form `set theFileName[%i%]=%%a` to `set theFileName[!i!]=%%a` Now i did that when the script run the output in line 36 show me NONE but in the previous version it shows the name of the excel file. I didn't know why should i use the delayed expension at the first place – Mohamed ISMAIL Dec 28 '20 at 11:46
  • can you please remove the old code and paste your newest code into the question and adapt the description to your remaining issues, so we can be sure to speak about the same things? Btw: you never defined `%theFileName[0]%`. – Stephan Dec 28 '20 at 13:11
  • The javascript code you've posted is, I presume, not representative of the task you've laid out, because it appears that is beginning at `0` and incrementing up until `n`, which you've not told us anything about. Batch files do not have an array feature, so all you are doing is creating a listing of variables with same names with an incremented integer in brackets. It would help us if you were to remove the code lines you've commented out improperly, _(`REM` is the proper command)_, and explain exactly what the intent is. How are you intending to use those individually defined variables? – Compo Dec 28 '20 at 15:40

1 Answers1

0

The following is a basic example of what I think you're trying to do, up to a point.

The problem is that because you've not told us what exactly you're intending to do with those similarly named variables, I cannot include the specific methodology for doing so. I have therefore just output the defined variable names along side their value strings.

@SetLocal EnableExtensions DisableDelayedExpansion
@For /F "Delims==" %%G In ('"(Set File[) 2> NUL"') Do @Set "%%G="
@Set "i=0" & For /F Delims^= %%G In (
    '"(Set PATHEXT=) & "%__APPDIR__%where.exe" ".:*.xlsx" ".:*.xls" ".:*.csv" 2> NUL | "%__AppDir__%sort.exe""'
) Do @(Set /A i += 1 & SetLocal EnableDelayedExpansion
    For %%H In (!i!) Do @EndLocal & Set "File[%%H]=%%~nxG")
@If Defined File[1] For /L %%G In (1,1,%i%) Do @(SetLocal EnableDelayedExpansion
    Echo File[%%G]=!File[%%G]! & EndLocal)
@Pause

The code above should define individual variables, each containing the string value of a file in the current directory, which has an extension of either .xlsx, .xls, or .csv.


When I first looked at your question I initially thought that you were intending to pass each file name together as multiple arguments to your node command.

If that is what you're actually intending to do, then I'd assume the following example would suit your purposes better.

@SetLocal EnableExtensions DisableDelayedExpansion
@Set "FileList="&For /F Delims^= %%G In (
    '"(Set PATHEXT=) & "%__APPDIR__%where.exe" ".:*.xlsx" ".:*.xls" ".:*.csv" 2> NUL | "%__AppDir__%sort.exe""'
) Do @If Not Defined FileList (Set "FileList="%%~nxG"") Else (SetLocal EnableDelayedExpansion
    For /F Delims^=^ EOL^= %%H In ("!FileList!") Do @EndLocal & Set "FileList=%%H "%%~nxG"")
@If Defined FileList Echo %%FileList%%=%FileList%
@Pause

The code above should define a single variable, containing the space separated, and doublequoted, string values, of each file in the current directory, which has an extension of either .xlsx, .xls, or .csv.

Please note that there is a command line length limitation so be aware that your value could become truncated.


In both examples:

  • The last line, @Pause, is included only to prevent premature closure of the cmd window, should you not be testing this from the CLI. (You can safely remove it if you are).

  • I assumed you wanted only the filenames without their paths, in the variable values. Should you wish for the full paths, just change %%~nxG in your chosen example code to %%G.

  • BTW, I used sort.exe against the returned files, because you mentioned array, and IMO an array should be ordered. (If you do not need that functionality, you could remove | "%__AppDir__%sort.exe" from your chosen example code).

  • Please note that there is a limit to the size of the environment, so be aware that if you have many matching files, they have long filenames, include paths etc. you may reach or exceed that limitation.


Having provided some examples for you, I'm not sure why you could not just iterate your directory, and create an array of those files, directly using .js, (off topic).

Compo
  • 36,585
  • 5
  • 27
  • 39
  • Thanks alot for your help. it actually answer my question! To be honest i didn't think of the second idea of (iterating my current directory and create an array of those files using js "i will try to implement it") But the main pupose of (main.js) is to remove the empty columns from all excel file in the current directory. – Mohamed ISMAIL Dec 28 '20 at 20:13