标题: [原创] 批处理判断变量值是否为空的终极方法 [打印本页]
作者: namejm 时间: 2009-4-6 20:36 标题: 批处理判断变量值是否为空的终极方法
很多时候,我们需要检查某个变量的值是否为空,以便做后续处理。
对于这个问题,很多人会毫不犹豫地选择 if "%str%"=="" …… 的句式,在早期的批处理中,还可以看到这样的语句:if [%str%]==[],有人把这两种写法称为“防空字符”。
可是,这样做真的能在各种复杂的情况下判断某个变量的值是否为空吗?
答案是否定的。
先来看 if [%str%]==[],当%str%为空值的时候,它无疑能成功地捕获到这一情况,但是,如果%str%中含有特殊字符,比如>、&之类,这条语句就会报错。
为了兼容这几个特殊字符,人们绞尽脑汁,想到了 if "%str%"=="" 语句,于是,>、&、|之类的特殊字符也能顺利通过验证了,这是防空字符的一大进步。
但是,这条语句也不是完美的,因为有一个特殊字符它完全没办法处理!
这个特殊字符是什么呢?
它就是双引号"本身!
我们执行一下如下代码:- @echo off
- set str="
- if "%str%"=="" (echo yes) else echo no
- pause
复制代码
CMD.EXE报错了:命令语法错误。
原来,上面这条if语句执行的是 if """=="" ……,引号起到分组字符串的作用,而引号对是就近匹配的:第一个引号和第二个引号配成一对,第三个引号和第四个引号配成一对,第五个引号和第六个引号配成一对……,这条if语句最终的执行的是 if "==……,但是引号始终要作为分组字符来使用的,而单个的引号没有找到下一个可匹配的引号,所以就出现了语法错误。
当把 %str% 的值改为两个引号的时候,上面这段代码的执行结果居然显示为no,想想这是为什么。
if "%str%"==""……能兼容大部分特殊字符,但是偏偏不能兼容引号本身,那么,判断某个变量的值是否为空,是不是就没有更好的办法了呢?
答案是肯定的,那就是:用 if defined str 语句来判断变量值是否为空。
请执行以下代码:- @echo off
- :Main
- cls
- set str=
- set /p "str=请输入任意字符,或直接回车:"
- if defined str (
- echo 变量 str 的值不为空
- ) else echo 变量 str 为空值
- pause
- goto Main
复制代码
作者: 随风 时间: 2009-4-6 22:31
呵,鸡蛋里挑点骨头 ^_^
用 if defined 判断某个变量是否被定义过时需注意以下2点:
1、变量名若含空格,不能直接输入空格,有空格时需用变量来代替,且必须是用双!!来引用这个含空格的变量
也就是必须开启延迟变量,或者将需判断的变量名赋值给 for 的 %%i 变量。
2、若判断的变量名需要使用变量的字符截取功能时,则与上面的正好相反。
即:不能使用!!来引用变量,即使是在for中也是一样。
http://www.bathome.net/viewthread.php?tid=2050&highlight=defined
[ 本帖最后由 随风 于 2009-4-6 22:33 编辑 ]
作者: yslyxqysl 时间: 2009-4-6 22:41 标题: 回复 2楼 的帖子
还不如用if "!var!"==""呢。
作者: namejm 时间: 2009-4-6 22:57
嗯,变量名中含有空格的写法是极其BT的,以前没怎么注意到,看来得花点时间折腾一下下。随风的研究结论,等本人测试过之后再决定是否补充到顶楼。
Re yslyxqysl:
我一般不使用if "!var!"=="" 的做法,因为局限性太大了,详情我在顶楼也有描述。
作者: 随风 时间: 2009-4-6 23:00
原帖由 namejm 于 2009-4-6 22:57 发表
嗯,变量名中含有空格的写法是极其BT的,.......
呵呵,所以我说是鸡蛋里挑骨头。。
作者: NeverOK 时间: 2009-5-5 22:55
专家到一个很高的水平了,都开始鸡蛋里挑骨头了,呵呵
作者: tempwork1 时间: 2009-5-19 15:42 标题: 不同意见-新手请教,请多批评
下面的程序是输入字符串,然后反向显示,并输出字符串个数。好像没有if "!var!"=="" 的问题啊。" % 都试过了
@echo off
setlocal enabledelayedexpansion
set out=K
set /p a1=请输入字符串:
set /a num=0
for /L %%i in (1,1,10000) do (
if "!a1!"=="" goto END
set out=!out!^!a1:~-1!
set a1=!a1:~0,-1!
set /a num=%%i
)
:END
IF /i !num! == 0 (echo 字符串为空) ELSE (echo !out:~1!字符串个数为 !num! )
pause
[ 本帖最后由 tempwork1 于 2009-5-19 16:08 编辑 ]
作者: namejm 时间: 2009-5-19 18:26
因为你的变量值中没有双引号,所以不会出错,请注意顶楼的全面描述,而不要以其中一种情况成立就否定顶楼的结论。
作者: 极品小猫 时间: 2012-6-13 11:08
正烦恼特殊字符的问题, 如果变量名包含空格的事情实在蛋疼啊~谁愿意这样折腾?
作者: CrLf 时间: 2012-6-13 11:52
回复 9# 极品小猫
用 for:- @echo off
- set "te st=测试1,只含空格或其他默认分隔符的情况"
- for %%a in ("te st") do if defined %%~a echo 存在变量 te st
- set "te* ?st=测试2,含 * 或 ? 的情况"
- for /f "eol== delims=" %%a in ("te* ?st") do if defined %%a echo 存在变量 te* ?st
- pause
复制代码
相比之下,for /f 更严谨通用
作者: 极品小猫 时间: 2012-6-14 13:01
回复 极品小猫
用 for:相比之下,for /f 更严谨通用
CrLf 发表于 2012-6-13 11:52
额~我表达有问题, 其实是两段回复
正在烦恼特殊的字符的问题(不是变量名, 是变量值), 上面回复后面的那段话无视吧.
批处理输入的时候, 如果变量值含有 > >> | 诸如此类的如何预处理, 详细的看下面的帖子
http://bbs.bathome.net/viewthread.php?tid=17450
作者: cjiabing 时间: 2012-6-25 21:34
大家比较下以下两个代码,看看 defined 与 if "%input%" == "" 的区别:
- @echo off
- :input
- cls
- set /p input=直接回车返回,输入【Y】结束:
- if defined input echo 你将返回开始!&pause&goto input
- if /i "%input%"=="Y" echo Over&pause&exit
- echo 输入错误,请重试!
- pause&goto input
复制代码
- @echo off
- :input
- cls
- set /p input=直接回车返回,输入【Y】结束:
- if "%input%"=="" echo 你将返回开始!&pause&goto input
- if /i "%input%"=="Y" echo Over&pause&exit
- echo 输入错误,请重试!
- pause&goto input
复制代码
在功能上:
1、defined “如果已定义环境变量,DEFINED 条件的作用跟 EXISTS 的一样,除了它取得一个环境变量,返回的结果是 true。”
它只有 真 与 假 两种情况,因此,判断变量是否为空,当然最基本的办法就是 if not defined var (echo not) else echo yes
2、相比较之下,if "%input%"=="" 则对空格比较敏感些,它可以将空格独立出来处理。
在互动时输入任意字符进行判断,输入空格表示值不存在,这样更符合平时的使用习惯。
文本是否为空的判断也一样,一个文本中只有一堆空格而没有其他任何字符,我们通常认为这个文本是空的,而非defined认为的文本不为空。
综上,defined在比较苛刻的有与无的判断时使用,而 if "%input%"=="" 则在空格也是空值进行判断时使用。
欢迎光临 批处理之家 (http://www.bathome.net/) |
Powered by Discuz! 7.2 |