我有下面的批处理脚本。它应该读取文本文件的每一行的第一个字符。这是一个到z,它应该在相应的文件夹中创建一个子文件夹。它是其他的东西,它应该在“_other”文件夹中创建。
所以,如果我有一个清单:
123test
aaatest
bbbtest
它应该创建:
c:\dirs\_other\123test
c:\dirs\a\aaatest
c:\dirs\b\bbbtest
但由于某种原因,我的最后一个if / else不起作用。为什么不?这是剧本:
setlocal EnableDelayedExpansion
set file=c:\klantenlijst.txt
FOR /F "delims=~" %%i IN (!file!) DO (
set var=%%i
set str=!var:~0,1!
IF !str!==A ( set letter=1 )
IF !str!==B ( set letter=1 )
IF !str!==C ( set letter=1 )
IF !str!==D ( set letter=1 )
IF !str!==E ( set letter=1 )
IF !str!==F ( set letter=1 )
IF !str!==G ( set letter=1 )
IF !str!==H ( set letter=1 )
IF !str!==I ( set letter=1 )
IF !str!==J ( set letter=1 )
IF !str!==K ( set letter=1 )
IF !str!==L ( set letter=1 )
IF !str!==M ( set letter=1 )
IF !str!==N ( set letter=1 )
IF !str!==O ( set letter=1 )
IF !str!==P ( set letter=1 )
IF !str!==Q ( set letter=1 )
IF !str!==R ( set letter=1 )
IF !str!==S ( set letter=1 )
IF !str!==T ( set letter=1 )
IF !str!==U ( set letter=1 )
IF !str!==V ( set letter=1 )
IF !str!==W ( set letter=1 )
IF !str!==X ( set letter=1 )
IF !str!==Y ( set letter=1 )
IF !str!==Z ( set letter=1 )
IF !letter!==1 ( md c:\Dirs\!str!\!var! ) ELSE ( md c:\Dirs\_Other\!var! )
)
答案 0 :(得分:5)
这就是我这样做的方式:
@echo off
setlocal EnableDelayedExpansion
set letters=ABCDEFGHIJKLMNOPQRSTUVWXYZ
set file=c:\klantenlijst.txt
FOR /F "delims=" %%i IN (%file%) DO (
set var=%%i
set str=!var:~0,1!
for %%a in ("!str!") do if "!letters:%%~a=!" equ "%letters%" set str=_other
md "c:\dirs\!str!\!var!"
)
上面的程序试图从包含所有字母的字符串中删除第一个字符;如果结果相同,那么第一个字符不是字母。此方法更快,因为它不使用任何外部.exe命令。
编辑:添加了一些解释
在下面的示例中,我先写一个命令,然后再输出它。
letters
变量包含26个字母,即:
echo !letters!
ABCDEFGHIJKLMNOPQRSTUVWXYZ
Batch允许以这种方式替换部分变量值:
echo !letters:M=123!
ABCDEFGHIJKL123NOPQRSTUVWXYZ
如果没有给出替换字符串,则只删除原始子字符串:
echo !letters:M=!
ABCDEFGHIJKLNOPQRSTUVWXYZ
如果原始子字符串包含在另一个变量中,则使用其值实现替换。例如,如果变量有一个字母:
set str=M
echo !letters:%str%=!
ABCDEFGHIJKLNOPQRSTUVWXYZ
另一方面,如果变量没有字母,则新值保持与原始值相同:
set str=1
echo !letters:%str%=!
ABCDEFGHIJKLMNOPQRSTUVWXYZ
这样,如果您比较"!letters:%str%=!"
与"%letters%"
;如果结果是DIFFERENT,则str变量包含一个字母;否则str变量包含非字母字符。
但是,您必须注意str变量在 FOR循环中被修改。这意味着必须使用DelayedExpansion替换其值,但这导致以下有趣的代码:"!letters:!str!=!"
当然无效。修复此细节的方法是通过FOR可替换参数更改!str!
值,然后使用替换子字符串表达式中的参数。
您必须注意,以前的替换是由cmd.exe处理器立即实现的,因为正常处理批处理文件。另一方面,执行ECHO !str! | FINDSTR /I "[A-Z]"
需要加载FINDSTR.EXE文件(大约30 KB大小)和执行CMD.EXE的两个副本以执行每一方管道的这个过程是为列表中的每个名称执行!。这意味着此方法比前者慢得多,如果名称列表很大,时间差异将很明显。
答案 1 :(得分:3)
您可以使用FINDSTR
来测试第一个字符是否为字母:
...
ECHO !str! | FINDSTR /I "[A-Z]" 1>NUL && (
command to execute if !str! is a letter
) || (
command to execute if !str! is not a letter
)
...
"[A-Z]"
模式匹配任何字母,/I
开关使匹配不区分大小写。
例如,如果str
不是字母,您可以将_other
设置为...
ECHO !str! | FINDSTR /I "[A-Z]" 1>NUL || (
SET str=_other
)
MD "c:\Dirs\!str!\!var!"
...
。这样,当使用该值作为应在其中创建子文件夹的文件夹的名称时,您将不再需要任何条件:
MD
请注意{{1}}中路径周围的双引号。当路径包含空格或其他特殊字符时,这是必要的。 (谢谢@Peter Wright的说明。)
答案 2 :(得分:2)
这是验证字符是否为字母的另一种快速方法。
@echo off
setlocal EnableDelayedExpansion
set file=c:\klantenlijst.txt
for /f "delims=" %%i IN (%file%) do (
set var=%%i
set str=!var:~0,1!
if /i "!str!" geq "A" if /i "!str!" leq "Z" set "str=_other"
md "c:\dirs\!str!\!var!"
)
这种方法的一个不同之处在于,带有变音符号的非英文字母也将被视为字母。这些非英文字母都有扩展的ASCII码大于127.这与Andriy的FINDSTR方法得到的结果相同。
答案 3 :(得分:1)
这不适用于a
,仅适用于A
:
IF !str!==A ( set letter=1 )
将其替换为:
IF /i !str!==A ( set letter=1 )