【问题标题】:DIR output into BAT array?DIR 输出到 BAT 阵列?
【发布时间】:2012-05-19 15:41:42
【问题描述】:

有没有办法将“dir”命令的输出读入 BAT 文件中的数组?还是我需要先将其输出到文件,然后读取文件并删除文件?

目的是获取目录中的文件夹列表,为每个文件夹附加一个数字,然后提示用户输入数字以选择文件夹。

更新:明白了!

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

【问题讨论】:

标签: arrays batch-file


【解决方案1】:

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%!

在上面的代码中,“数组”元素被命名为folder1、folder2、folder3...

有些人使用文件夹[1]、文件夹[2]、文件夹[3]...等名称。它当然看起来更像数组,但这正是我不这样做的原因。对批处理不太了解的人看到这样的变量并假设批处理正确支持数组。

如果任何文件夹名称包含! 字符,上述解决方案将无法正常工作 - 由于延迟扩展,文件夹名称将在 %%F 变量的扩展过程中损坏。有一种解决方法涉及打开和关闭延迟扩展,但除非需要,否则不值得进入。

【讨论】:

  • 是的,这与我想出的解决方案相同,谢谢。有什么理由使用引号?
  • @user1229895 - 不需要引号,但它们可以非常明确地说明 SET 分配的结束位置。只要开始引号在变量名之前,那么最后引号之后的任何文本都会被忽略。 SET "var=value" junk 将 var 设置为 value 并忽略垃圾。它使提示符末尾有一个空格在视觉上很明显,并且它可以防止两个 SET 语句中无意添加空格。
【解决方案2】:

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

我对此事的看法与dbenhams 的完全相反。在我看来,在回答 Batch 主题时,我们必须非常简洁明了,尤其是对于初学者,并提供有助于解决问题的最少信息,但不要压倒答案并使答案混淆。在 Batch 中模拟数组有两种方式:通过广泛使用的方括号括住下标,或者不通过,但在这两种情况下概念是相同的:选择一个通过数字索引从同名变量列表中的特定元素。

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

如果使用方括号,初学者会发现大量关于“数组”概念的信息和许多编程语言中关于此主题的大量示例,甚至是独立于任何编程语言的描述,当然,这些语言可以立即使用在批处理文件中。在这种情况下使用方括号比不这样做要清楚得多。但是,有些人认为这些好处不值得假设 Batch“正式支持数组”的“混乱”。

在我看来,这件事的中心点不是讨论 Batch 是否正式支持数组,而是任何人都可以使用数组概念来操作 Batch 文件中的数据这一事实。我认为有些人可能认为 Batch 正确支持数组,尤其是初学者,这完全没有问题;数组管理在不同的编程语言中是不同的,所以只需要解释批处理细节。但是,如果对这个主题进行更正式的讨论似乎很重要,我想举一个不同的例子。

您知道 C 编程语言不“正式支持”任何输入-输出操作吗?当 Dennis Ritchie 设计它时,他专门将这些操作留在了语言设计之外,以保持编译器小巧紧凑。这是否意味着您不能在 C 程序中读/写任何数据?当然不是!这只是意味着这些操作是通过函数库在编译器外部实现的,所以如果你需要开发一个 C 编译器,你不必担心如何编译 PRINT、READ 或任何其他 I/O声明,因为它们在 C 语言中不存在!

很有趣,不是吗?

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

好吧,依我的拙见,对于 Batch 中的数组,应该使用相同的方法。

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

用户rojo对此点的看法:

这是一个迂腐的论点,无法解决提问者试图解决的问题

(见上面this answer他的完整评论)。

【讨论】:

  • @RichardHarrison, user66001:感谢两位的纠正。英语不是我的奶舌!安东尼奥
  • 我在已发表的学术著作中被引用和引用。我感到非常荣幸!这是我的最高成就,是我存在的巅峰。
猜你喜欢
  • 2017-09-24
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-05-11
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多