此代码:
@echo off
setlocal enableextensions enabledelayedexpansion
set "var=string"
set /P q="How many subdirectories would you like to add in each folder? "
for /l %%x in (1, 1, %q%) do (
set /P c="What is the name of subdirectory %%x? "
for /F "tokens=1 delims=\n" %%d IN (list.txt) DO md "%%d\!c!"
)
基于列表文件创建文件夹,并根据用户输入将子目录添加到每个文件夹中。子目录创建正确,但是名称列表在定界符周围有一些时髦的行为。这是一个假设的列表:
7 Jonathon, Hasselhoff B
7 Dean, Granger P
7 Dean, Jimmy C
7 Norris, Chuck J
7 Chan, Jackie S
通过上面的代码运行此列表将产生以下文件夹名称:
7 Jo
7 Dea
7 Norris, Chuck J
7 Cha
如果我更改代码以使delims="
可以正常工作。谁能解释为什么?
答案 0 :(得分:1)
对于此任务,我建议使用以下批处理文件:
@echo off
setlocal EnableExtensions EnableDelayedExpansion
:GetFolderCount
set "FolderCount="
set /P "FolderCount=How many subdirectories would you like to add in each folder? "
rem Has the user entered anything at all?
if not defined FolderCount goto GetFolderCount
rem Has the user entered a string not consisting only of digits?
for /F delims^=0123456789^ eol^= %%I in ("!FolderCount!") do goto GetFolderCount
rem Has the user entered a positive integer too large for Windows command
rem processor or being interpreted octal by cmd.exe because of leading zeros?
set /A TempCount=FolderCount
if not %TempCount% == %FolderCount% goto GetFolderCount
set "TempCount="
if not %FolderCount% == 0 (
for /L %%I in (1,1,%FolderCount%) do (
set "FolderName="
set /P "FolderName=What is the name of subdirectory %%I? "
if defined FolderName for /F "eol=| delims=" %%J in (list.txt) do md "%%~J\!FolderName!"
)
)
endlocal
批处理文件不相信用户输入的内容总是正确的正整数。因此,批处理文件首先删除环境变量FolderCount
。
接下来,它会提示批处理文件用户输入子目录数。如果用户只是按下 RETURN 或 ENTER 导致再次提示用户,则FolderCount
仍未定义。还可以在提示用户设置默认值之前,通过按 RETURN 或键,用FolderCount
之类的值来定义1
ENTER 。
用户可以有意输入或错误输入任何字符串,而不仅仅是批处理文件期望的正整数。因此,接下来需要验证输入的字符串实际上仅包含数字。
使用选项/F
的 FOR 会忽略空字符串(不再可能)和以;
开头的字符串。输入的以分号开头的字符串应被解释为错误的输入,这是将默认eol=;
重新定义为eol=
来定义无行尾字符的原因,因此不要忽略与字符串无关的字符串第一个字符。
FOR 使用默认空格和水平制表符作为子字符串的分隔符,将字符串拆分为子字符串(令牌),并仅将第一个子字符串分配给指定的循环变量I
。通过用delims=0123456789
指定所有数字作为分隔符,可以修改此字符串拆分行为。如果用户输入的字符串仅由数字组成,则 FOR 循环将不执行命令 GOTO ,因为在这种情况下,不能为循环变量I
分配任何内容。但是,如果用户输入的字符串中还有其他任何字符,则 GOTO 命令将由 FOR 执行,在这种情况下,会将某些内容分配给循环变量。
使用另一种非双引号方法来定义定界符列表,并且不使用行尾字符,这要求使用字符插入符号^
来转义两个等号和两个选项之间的空格字符这样,根据 FOR 语法的要求,整个选项字符串将被解释为一个参数字符串。
通过此检查后,用户输入的字符串肯定仅包含数字。
但是它可以有前导零,从而导致解释八进制数或该数字太大,如439871023842
。因此,使用算术表达式将用户输入的字符串分配给另一个环境变量,在这种情况下,该结果导致将用户输入的字符串转换为值范围为0
至2147483647
的32位有符号整数因为-
开头已经不可能了。接下来,将所得的整数转换回分配给环境变量TempCount
的字符串。因此,如果分配给TempCount
的字符串不等于分配给FolderCount
的字符串,则用户输入的值将不满足作为正32位十进制整数值的要求。
仍然可能的是,用户输入了0
作为子目录的数目,在这种情况下,根本不会执行下一个块,而根据用户的输入则无所事事。
在循环中提示用户输入文件夹名称之前,始终会删除环境变量FolderName
。因此,用户必须始终输入文件夹名称,否则将无法进行任何操作。如果应该再次使用子目录的先前输入名称,则用户可以使用键 UP 一次或多次。
在用户输入一个非空字符串后,将按预期创建子目录,该字符串对于当前目录中文件list.txt
中定义的每个子目录中的文件夹名称均有效。
这次使用选项/F
和list.txt
修改了带有选项eol=|
的 FOR 命令以从文件delims=
读取行在双引号参数字符串中指定,由于指定了空的定界符列表,因此不会忽略以分号开头的行,也不会将每一行拆分为子字符串。竖线代替;
,因为文件夹名称不能包含竖线,而文件夹名称开头可以使用分号。
因此,您已经用delims=\n
定义了反斜线或字母n
上的行,而以delims=
结尾的可选参数字符串定义了一个空的定界符列表,从而关闭了字符串/行如果不以竖线开头,则完全拆分行为并将其分配给指定的循环变量J
始终是从列表文件读取的整个非空行。
注意:由于启用了延迟的环境变量扩展,list.txt
中包含一个或多个感叹号的目录名称未正确处理。但这似乎没问题。
要了解所使用的命令及其工作方式,请打开命令提示符窗口,在其中执行以下命令,并非常仔细地阅读每个命令显示的所有帮助页面。
echo /?
endlocal /?
for /?
goto /?
if /?
md /?
rem /?
set /?
setlocal /?