找回密码
 注册
搜索
[新手上路]批处理新手入门导读[视频教程]批处理基础视频教程[视频教程]VBS基础视频教程[批处理精品]批处理版照片整理器
[批处理精品]纯批处理备份&还原驱动[批处理精品]CMD命令50条不能说的秘密[在线下载]第三方命令行工具[在线帮助]VBScript / JScript 在线参考
楼主: qzwqzw

[其他] [50条]不能说的秘密-CMD命令奇诡语法特性汇集

[复制链接]
 楼主| 发表于 2010-4-19 16:57:26 | 显示全部楼层

回复 14楼 的帖子

第一次使用帖子的"引用"
好麻烦

当 test.txt 最后一行不是空行的时候,将获取最后一行的内容


这样的描述很别扭
让我掂不清是最后一行
还是倒数第二行

你在顶楼归纳的那4种情况其实就是一个大的分类啊,在这些分类下面,再按照字母顺序排下来就是了。

我不是专指分类
而是指索引
也就是快速定位的方式方法
比如分楼显示加楼层锚点

正在试for
一头雾水中……
独郁闷不如众郁闷
发上来
也让大家伙费费脑筋
D:\>echo %errorlevel%
0

D:\>(for /f %f in (test) do do set)
系统找不到文件 test。

D:\>echo %errorlevel%
0

D:\>(for /f %f in (test) do do set) 2>nul

D:\>echo %errorlevel%
0

D:\>(for /f %f in (test) do do set) || echo test
系统找不到文件 test。
test

D:\>echo %errorlevel%
5

D:\>(for /f %f in (test) do do set) 2>nul || echo test
test

D:\>echo %errorlevel%
6

D:\>(for /f %f in (uni.txt) do do set) || echo test
test

D:\>echo %errorlevel%
1

D:\>(for /f %f in (uni.txt) do do set) 2>nul || echo test
test

D:\>echo %errorlevel%
1

D:\>(for /f %f in (uni.text) do do set) || echo test
系统找不到文件 uni.text。
test

D:\>echo %errorlevel%
2

D:\>

注释:D盘根存在名为Test的目录

[ 本帖最后由 qzwqzw 于 2010-4-19 17:09 编辑 ]
发表于 2010-4-19 16:57:34 | 显示全部楼层
有一个问题算不上诡异,但多数新手却很容易找不到错误的原因:
  1. set a=
复制代码
这个是很多人经常用的一行代码,但却产生了一个问题。如果在这之前没有定义变量a,则这行代码后会产生%ERRORLEVEL%为1。
例如:
  1. @echo off
  2. echo.%ERRORLEVEL%
  3. set a=
  4. echo.%ERRORLEVEL%
  5. pause
复制代码
这将直接干扰后面对%ERRORLEVEL%的使用

[ 本帖最后由 hanyeguxing 于 2010-4-20 19:20 编辑 ]

评分

参与人数 1PB +30 技术 +1 收起 理由
qzwqzw + 30 + 1 决定采用,以资鼓励

查看全部评分

 楼主| 发表于 2010-4-19 17:02:21 | 显示全部楼层
errorlevel 的细节还很多
足可以单独盖一栋楼了
这是打的基础
http://bbs.bathome.net/thread-7479-1-1.html
 楼主| 发表于 2010-4-19 17:24:43 | 显示全部楼层

回复 14楼 的帖子

呵呵,我的本意是 for 语句不能直接读取Unicode编码的文本,需要借助type或more。

得你提醒
又发现一系列”非奇诡“的奇诡
D:\>cmd /u /c echo test123>uni.txt

D:\>more uni.txt
test123

D:\>type uni.txt | more
t
e
s
t
1
2
3


D:\>cmd /u /c echo 测试>uni.txt

D:\>more uni.txt
Km諎

逐字分行又多一个思路

[ 本帖最后由 qzwqzw 于 2010-4-19 17:25 编辑 ]
 楼主| 发表于 2010-4-19 23:53:20 | 显示全部楼层
而第8条描述是是多个数值赋值语句可以写成一行。

set /a 的逗号表达式在命令行帮助和windows帮助中都有提到
大家的代码里也经常用到
而且很多高级语言也支持逗号表达式
所以说明写的简略一点也说得过去

不过你到提醒了我另外一点
做个更新备忘:
set "var=3  > 2   "
 楼主| 发表于 2010-4-20 16:33:11 | 显示全部楼层

回复 14楼 的帖子

第7条的重点是描述 set /a 在不同版本的系统上有不同的表现;

关于set/a在xp sp3下的表现我这里与你所述不同


已确认,无论在哪种环境下
set /a var=abc都不会出错
因为它将abc识别为变量名,所以计算结果为0
set /a var=1a都会出错
因为它将1a识别为操作数,所以计算出错

set/a识别变量名和操作数的标准
应改就是是否以字母打头,还有一些其它特殊字符也可以
发表于 2010-4-20 16:47:29 | 显示全部楼层
你该用set/a "n=寒夜孤星"去实验,嘿嘿
在sp3下,set/a首先判断是否是数字(第一个字符是否是数字或数字符号),然后判断是否为有效数字
 楼主| 发表于 2010-4-20 17:03:57 | 显示全部楼层
我已经确认问题细节
你再看一下的我的21楼帖吧
示例:
set /a var=_abc
set /a var2=1a

效果:第一句会将变量var赋值为0,第二句会报“无效数字”的语法错,且不会对变量var2赋值
注释:第一句set/a将_abc识别为变量名,因找不到对应变量,所以赋值结果为0;
        第二句set/a将1a识别为操作数,而它又不是一个合法的数值,所以提示语法错误。
        set/a的判断变量名和操作数的标准类似高级语言:字符串以数字起始是操作数,否则为变量名。
        此外,判断一个字符串是否是合法的十进制数值的方法如下:
        set /a _var=%var% 2>nul
        if "%_var%"=="%var%" echo %var%是合法的十进制数值

[ 本帖最后由 qzwqzw 于 2010-4-20 17:06 编辑 ]
发表于 2010-4-20 17:04:08 | 显示全部楼层

回复 16楼 的帖子

实在没看明白你郁闷的是什么地方
D盘根目录下存在 uni.txt  uni.text 这两个文件吗?
如果不存在,那么cmd 返回信息似乎没什么不对的地方呀?
你在最后注释 D盘根目录存在 test 目录是什么意思?for /f 本就不能遍历文件夹吧。
 楼主| 发表于 2010-4-20 17:09:29 | 显示全部楼层

回复 24楼 的帖子

测试环境D盘根有文件uni.txt和目录test,没有uni.text
请注意几种情况下不同的errorlevel
我们以为是相同的错误情况
结果出现了不同的errorlevel
发表于 2010-4-20 17:23:24 | 显示全部楼层
对cmd这些底层的东西向来是敬而远之~
qzwqzw 的功力真是令人羡慕,赞一个先。

下面有几个应该算不上是奇诡,但也有些特殊之处

if defined ab cd  无法检测含空格的变量名是否定义。
相关讨论 http://bbs.bathome.net/viewthread.php?tid=2050&highlight=defined

一种比较另类的变量截取
http://bbs.bathome.net/viewthrea ... ge=1&extra=page%3D4

楼主在13说的 关于for /f usebackq 的奇诡语法 在这里
http://bbs.bathome.net/viewthrea ... hlight=%C1%E9%D2%EC

[ 本帖最后由 随风 于 2010-4-20 17:29 编辑 ]

评分

参与人数 1PB +30 技术 +1 收起 理由
qzwqzw + 30 + 1 正在分析,先加分吧

查看全部评分

发表于 2010-4-20 17:43:26 | 显示全部楼层
原帖由 qzwqzw 于 2010-4-19 17:24 发表

得你提醒
又发现一系列”非奇诡“的奇诡

逐字分行又多一个思路

实际应用中受到很大的限制
1,对于ANSI编码的,必须使用cmd /u去转换
2,ANSI编码的文本内要求只能有字母、英文符号和数字
不过想到个简单的显示20个空行的方法,哈哈:
  1. fsutil file createnew uni.txt 20
  2. type uni.txt | more
复制代码

[ 本帖最后由 hanyeguxing 于 2010-4-20 18:02 编辑 ]
 楼主| 发表于 2010-4-20 19:24:14 | 显示全部楼层

回复 27楼 的帖子


简单问题复杂化
显示20个空行
这样不更简单吗
for /l %i in (1,1,20) do echo.


逐字分行的意义
不在于分行显示
而在于分行处理
比如下面的代码
  1. for /f %f in ('cmd /u /c echo test^|more') do @echo value=%f
复制代码
在这个意义下
我们通常处理的是单个字符串变量
那么西方字符集的限制就不是什么大问题
至于cmd /u
闲着也是闲着
干嘛不用呢?

[ 本帖最后由 qzwqzw 于 2010-4-20 19:31 编辑 ]
发表于 2010-4-20 19:30:59 | 显示全部楼层
问题在于我就是通过这个才认清more逐字分行的原因啊,嘿嘿
发表于 2010-4-20 20:13:29 | 显示全部楼层
又发现一个奇诡的问题
以下代码,不管是否存在a.txt都无法正确运行,把rem 换成其它的命令则可以,或去掉最外面的一对括弧也可以。
  1. @echo off
  2. (for /f %%f in (a.txt) do echo.123&rem abc)
  3. pause
复制代码
您需要登录后才可以回帖 登录 | 注册

本版积分规则

Archiver|手机版|小黑屋|批处理之家 ( 渝ICP备10000708号 )

GMT+8, 2026-3-16 23:50 , Processed in 0.022357 second(s), 8 queries , File On.

Powered by Discuz! X3.5

© 2001-2026 Discuz! Team.

快速回复 返回顶部 返回列表