批量获取变量位置的数组值时出现异常行为 [英] Unexpected behaviour when retrieving array values at variable position in batch
问题描述
我目前正在分批尝试,并写了这个文件来计算目录中的.mkv和.srt文件,这种行为的方式我不理解:
I am currently trying my hand at batch, and wrote this file for counting .mkv and .srt files in a directory, which behaves in a way I don't understand:
@echo off
setlocal EnableDelayedExpansion
set /A mkvCounter=0
set /A srtCounter=0
set mkvFileName=empty
::Count .mkv files in directory
for %%f in (*.mkv) do (
set /A mkvCounter=mkvCounter+1)
::Count .srt files in directory
for %%f in (*.srt) do (
set /A srtCounter=srtCounter+1)
IF NOT %mkvCounter%==1 (
echo There is more than 1 .mkv file in this directory
set counter=1
for %%f in (*.mkv) do (
set a[!counter!]=%%f
echo !counter!: %%f
set /a counter=counter+1
)
:enterMkvNumber
REM Check if the number is valid
echo select the number of the .mkv file that you want to merge
set /p num="Number: "
if not !num! GEQ -1 (
echo Error invalid input, select number between 0 and !mkvCounter!
GOTO :enterMkvNumber
)
if not !num! LEQ !mkvCounter! (
set /A max=!mkvCounter
echo Error invalid input, select number between 0 and !mkvCounter!
GOTO :enterMkvNumber
)
echo Selected Mkv File: !a[%num%]!
)
endlocal
EXIT /B
echo Selected Mkv File:!a [%num%]!
行将打印"Selected Mkv File:".当我执行文件并输入有效数字时,表明!a [%num%]!
不返回任何内容.
The echo Selected Mkv File: !a[%num%]!
line prints "Selected Mkv File: " when I execute the file and enter a valid number, indicating that !a[%num%]!
returns nothing.
当我不输入有效数字时,即程序提示我第二次输入该数字,然后输入有效数字. echo Selected Mkv File:!a [%num%]!
创建所需的选定的Mkv文件:myFile.mkv"输出.
When I don't enter a valid number, i.e. the program prompts me to enter the number a 2nd time, and then enter a valid number echo Selected Mkv File: !a[%num%]!
creates the desired output of "Selected Mkv File: myFile.mkv".
Example output:
There is more than 1 .mkv file in this directory
1: asdf.mkv
2: hehe.mkv
3: yep.mkv
select the number of the .mkv file that you want to merge
Number: 1
Selected Mkv File:
有人知道是什么原因造成的和/或如何解决?
Does anyone know what causes this and/or how to fix it?
推荐答案
让这个旋转一下.它使用宏来处理数组,动态菜单和文件选择的定义.
Give this one a spin. It uses macros to handle the definition of arrays, Dynamic menus and file selection.
@Echo Off & Setlocal DisableDelayedExpansion
::: ************************************************************** || Macro Definitions
::: Delayed expansion must be enabled AFTER definition of macros, and BEFORE their use.
Set "TAB= "
Set "Menu=Echo/!DIV!&For %%n in (1 2)Do if %%n==2 ((Set "CHCS="&For %%G in (!Options!)Do (Set "Opt=%%~G"& Set "CHCS=!CHCS!!Opt:~0,1!"&Set "Opt[!Opt:~0,1!]=%%~G"& Set "Opt=[!Opt:~0,1!]!Opt:~1!"& Echo/!Opt!))&Echo/!DIV!& For /F "Delims=" %%o in ('Choice /N /C:!CHCS!')Do (For %%C in (!Opt[%%o]!)Do (Set "OPTION=%%C")))Else Set Options="
Set "DEF/array=(If "!#$E!"=="" (Set "#$E=-1"))&For %%n in (1 2)Do if %%n==2 (Set /A "#$E+=1"&Set "$E=!$E!"&For %%G in (!$E!)Do (Set "$E[!#$E!]=%%~G"))Else Set $E="
rem // extension type provided using Substring modification to replace $E
Set "SelectFile=(If Not !#$E! GTR 0 (Echo/No $E Files found. & Exit /B 0))& (For /L %%i in (0 1 !#$E!) Do If Not "!$E[%%i]!"=="" Echo/%%i:!TAB!!$E[%%i]!)&Echo/Select a $E file number [0-!#$E!]:&Set /P "FN=FN: "&For %%v in ("!FN!")do (If /I "!FN!"=="Exit" (Exit /B 0)Else If not "!$E[%%~v]!"=="" (Set "PATH[$E]=!$E[%%~v]!"&Echo/!$E[%%~v]! Selected)Else (Goto :$E))"
rem // selected path returned in !PATH[ext]!
::: ************************************************************** || End Macro Definitions
Setlocal EnableExtensions EnableDelayedExpansion
::: Build Dividing line based on actual console dimensions.
for /F "usebackq tokens=2* delims=: " %%W in (`mode con ^| findstr Columns`) do Set "Console_Width=%%%W"
Set "DIV="&For /L %%i in (2 1 %Console_Width%)Do Set "DIV=!DIV!-"
::: ************************************************************** || Script Body
Set "SourceDir=%~dp0"
PUSHD "%SourceDir%"
For %%O in (*.mkv)Do %DEF/array:$E=mkv%"%%~fO"
For %%O in (*.srt)Do %DEF/array:$E=srt%"%%~fO"
:menu
cls & Echo/.mkv Files:!#mkv! .srt Files: !#srt!
%Menu%mkv Srt Exit
If /I "!Option!"=="Exit" (POPD & Endlocal & Endlocal & Goto :Eof) Else Call :!Option!
PAUSE
Goto :menu
:mkv
%SelectFile:$E=mkv%
Exit /B 0
:srt
%SelectFile:$E=srt%
Exit /B 0
标记无效的输入,因为该输入用于索引数组元素.错误的输入会导致元素为空,并触发返回扩展标签,而selectFile宏通过子字符串修改在扩展时提供给扩展标签.
Invalid input is flagged as the input is used to index the array element. False input results in an empty element which triggers a return to the extension label the selectFile macro is provided with at expansion via substring modification.
---------------------------------------------------------------------------------------
- 菜单宏:
- 用DIV变量中的值显示分隔线并...
- 使用if else else for循环捕获,修改和显示要用于菜单选项的字符串.
- 每个字符串的第一个字符用作用户选择的选择字符
- 如果提供了多个包含相同第一个字符的字符串,则会失败.
- 为每个字符串分配一个索引值,该索引值用于返回OPTION变量中的所选字符串
- 使用Choice命令的输出,该命令是使用For/F %% o循环捕获的.
Echo/!DIV! & For %%n in (1 2)Do if %%n==2 (
Set "CHCS="
For %%G in (!Options!)Do (
Set "Opt=%%~G"
Set "CHCS=!CHCS!!Opt:~0,1!"
Set "Opt[!Opt:~0,1!]=%%~G"
Set "Opt=[!Opt:~0,1!]!Opt:~1!"
Echo/!Opt!
)
Echo/!DIV!
For /F "Delims=" %%o in ('Choice /N /C:!CHCS!')Do For %%C in (!Opt[%%o]!)Do Set "OPTION=%%C"
)Else Set Options=
---------------------------------------------------------------------------------------
- DEF/数组宏:
- 扩展了子字符串修改,将$ E替换为用于给定数组的变量名
- 初始If条件准备一个未定义的数组以从0索引开始递增
- 使用If/Else外部for循环捕获数组元素,并将其分配给数组中递增的索引值
(If "!#$E!"=="" (Set "#$E=-1")) & For %%n in (1 2)Do if %%n==2 (
Set /A "#$E+=1"
For %%G in (!$E!)Do Set "$E[!#$E!]=%%~G"
)Else Set $E=
---------------------------------------------------------------------------------------
- SelectFile宏:
- 测试数组的索引值是否为正数,如果失败则返回上一级菜单
- 在扩展期间从0索引遍历数组以$ E替换的变量,并输出定义的文件
- 及其索引号供选择.数组名称与相关标签共享,以允许在以下情况下返回正确的标签
- 通过Set/P提供无效的输入来选择索引文件
- 将文件路径分配给变量Path [$ E],再次,在扩展过程中通过子字符串修改将$ E替换为相关文件类型.
If Not !#$E! GTR 0 (Echo/No $E Files found. & Exit /B 0)
For /L %%i in (0 1 !#$E!) Do If Not "!$E[%%i]!"=="" Echo/%%i:!TAB!!$E[%%i]!
Echo/Select a $E file number [0-!#$E!]:&Set /P "FN=FN: "&For %%v in ("!FN!")do (
If /I "!FN!"=="Exit" (Exit /B 0)Else If not "!$E[%%~v]!"=="" (
Set "PATH[$E]=!$E[%%~v]!"
Echo/!$E[%%~v]! Selected
)Else (Goto :$E)
)
注意:为故障提供的代码不起作用,它刚刚被解构以使您更容易看到每个宏为实现结果所采取的步骤.
Note: code supplied for breakdowns is non-functional, it's just been deconstructed to allow you to more easily see the steps each macro takes to achieve the outcomes.
这篇关于批量获取变量位置的数组值时出现异常行为的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!