将DIR输出转换为BAT数组?

9
有没有办法在BAT文件中将“dir”命令的输出读入到数组中?还是需要先将其输出到文件中,然后读取文件并在之后删除文件?
目的是获取目录中的文件夹列表,在每个文件夹后附加一个数字,然后提示用户输入数字以选择文件夹。
更新:已解决!
SETLOCAL EnableDelayedExpansion
SET /A c=1

FOR /F "tokens=*" %%F in ('dir /on /b /a:d /p %svnLOCAL%') DO ( 
    ECHO !c!. %%F
    SET dir_!c!=%%F
    SET /a c=c+1    
)

REM test array
ECHO !dir_4!
ENDLOCAL

1
我建议您查看这个答案:https://dev59.com/62kw5IYBdhLWcg3wDWTL#10167990 - Aacini
2个回答

14

Batch文件不支持数组,但您可以使用环境变量来模拟数组。

@echo off
setlocal enableDelayedExpansion

::build "array" of folders
set folderCnt=0
for /f "eol=: delims=" %%F in ('dir /b /ad *') do (
  set /a folderCnt+=1
  set "folder!folderCnt!=%%F"
)

::print menu
for /l %%N in (1 1 %folderCnt%) do echo %%N - !folder%%N!
echo(

:get selection
set selection=
set /p "selection=Enter a folder number: "
echo you picked %selection% - !folder%selection%!

在上面的代码中,“array”元素被命名为folder1,folder2,folder3……

有些人使用像folder[1]、folder[2]、folder[3]……这样的名称。虽然它看起来更像数组,但正是因为这个原因我不这样做。对于不太了解批处理的人来说,这样的变量看起来像数组,他们就会认为批处理可以正确支持数组。

如果任何文件夹名称包含!字符,则上述解决方案将无法正常工作——由于延迟扩展,当%%F变量扩展时,文件夹名称将会损坏。虽然有一种解决方法涉及到切换延迟扩展开和关,但除非需要,否则不值得深入讨论。


是的,那就是我想出来的相同解决方案,谢谢。你用引号的原因是什么? - user1229895
1
@user1229895 - 引号不是必需的,但它们可以非常明确地表示SET赋值的结束位置。只要开头引号在变量名之前,那么最终引号后的任何文本都将被忽略。SET“var = value”junk设置var为value并忽略了junk。这使得末尾有一个空格在视觉上很明显,并防止在两个SET语句中无意中添加额外的空格。 - dbenham

10

这不是一个答案,而是对 dbenham 答案的大评论回复。

我对这个问题的看法与 dbenham 完全相反。在我看来,在针对批处理主题的答案中,我们必须非常简明易懂,特别是对于初学者,提供最少的信息来帮助解决问题,但不要让答案过于复杂和混乱。有两种方法可以“模拟”批处理数组:通过广泛使用的方括号来括起下标,或者不用方括号,但无论哪种情况,概念都是相同的:通过数字索引从具有相同名称的变量列表中选择特定元素。

如果不使用方括号,初学者将不理解核心概念;相反,他们可能会认为批处理文件使用了“奇怪的技巧”来解决问题。另一方面,有经验的程序员肯定会说:“嘿!这是一个数组,但用了不同的写法”。没有任何方式会将此功能误认为其他不同的事物,并且没有理由将其伪装成其他不同的事物。

如果使用方括号,初学者将发现关于“数组”概念的大量信息和许多编程语言上的示例,甚至独立于任何编程语言的描述,当然在批处理文件中是立即可用的。在这种情况下,使用方括号要清晰得多。但是,一些人认为这些好处不值得“混淆”,因为批处理没有“正式支持数组”的功能。

在我看来,这个问题的核心不在于讨论批处理是否正式支持数组,而在于任何人都可以使用数组概念来操作批处理文件中的数据。我认为,如果有些人可能认为 Batch 正确地支持数组,尤其是初学者,这并不会造成任何问题;不同的编程语言中数组管理方式不同,所以只需要解释一下 Batch 的细节即可。然而,如果对这个问题进行更正式的讨论似乎很重要,我想提出一个不同的例子。

你知道吗,C语言并没有正式支持任何输入输出操作?当Dennis Ritchie设计它时,他特意将这些操作排除在语言设计之外,以使编译器变得更小更紧凑。这是否意味着您不能在C程序中读取/写入任何数据?当然不是!这只是意味着这些操作是通过函数库在编译器之外实现的,因此如果您需要开发C编译器,您无需担心如何编译PRINT、READ或任何其他I/O语句,因为它们在C语言中不存在!

有趣吧?

因此,如果一个初学者问:“如何在C语言中写消息?”,您认为正确的答案应该是:“您不能。C语言并没有正式支持任何I/O语句,但可以通过库函数模拟这些操作。” 当然不是!大多数人通常会描述printf,但实际上几乎没有人提到printf()“不是C语言的一部分”,而我认为这是正确的。归根结底,如果有人认为C语言支持I/O操作,那么有什么问题?人们无论如何都可以在C程序中使用I/O操作,不管它们是如何实现的,对吧?

嗯,在我看来,批处理中应该采用相同的方法处理数组。

也许更接近的例子是:有很多关于“批处理中算术运算”的问题,答案通常是:“使用set /A命令”。我从来没有看到过一个回答指出“批处理文件不支持数值变量,只支持字符串,但可以通过几种方式模拟算术运算,比如set /A命令”。为什么?似乎纯粹主义者在谈论批处理中的数组时更加“纯粹”,但他们不关心其他主题,比如数字。我真的不明白频繁澄清“批处理不支持数组”的目的!

用户rojo对此发表了意见:

这是一个迂腐的争论,没有为提问者试图解决的问题提供任何解决方案。

(请参见他在此回答中的完整评论。)


我在一篇已发表的学术作品中被引用和引述。我感到非常荣幸!这是我的巅峰成就,我存在的顶峰。 - rojo

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接