[新手上路]批处理新手入门导读[视频教程]批处理基础视频教程[视频教程]VBS基础视频教程[批处理精品]批处理版照片整理器
[批处理精品]纯批处理备份&还原驱动[批处理精品]CMD命令50条不能说的秘密[在线下载]第三方命令行工具[在线帮助]VBScript / JScript 在线参考
返回列表 发帖
36# zqz0012005


由于某些原因,在运行前的预处理时 没有能够分割参数,这些参数会被作为一个整体传递给具体命令然后由具体命令再次进行参数分割。for和call会这么做的。当然有些命令是不会这么做的,比如echo。

TOP

delims与空格的一个问题
http://www.bathome.net/viewthread.php?tid=3692&page=1#pid23376
好像是for的一个bug:一般来说,多个相同字符会被当作一个字符(它们不是整体作为分隔符,新手往往问到这个问题)。但如果指定连续多个空格,空格将无法作为分隔符。
补充以前讨论的一个要点:如果分隔符集里面含有空格,空格必须放在最后。
  1. @echo off
  2. for /f "delims=aa" %%a in ("1a2") do echo %%a
  3. rem 下面的“宽空格”是两个空格(也可以更多)
  4. for /f "delims=  " %%a in ("1 2  3") do echo %%a
  5. for /f "tokens=1,2 delims=aa  " %%a in ("1 2a3  4") do echo %%a.%%b.
  6. pause
复制代码
1

评分人数

    • plp626: 看来我也是新手,学习之。技术 + 1
命令行参考:hh.exe ntcmds.chm::/ntcmds.htm
求助者请拿出诚心,别人才愿意奉献热心!
把查看手册形成条件反射!

TOP

19楼代码的目的已经说了,只是为了试验对分隔符转义后,可不可以让多个参数被整体当作成一个参数。
验证结果表明,就算转义了,对其他命令来说,仍然是不同的参数,而不是整体作为一个参数。
命令行参考:hh.exe ntcmds.chm::/ntcmds.htm
求助者请拿出诚心,别人才愿意奉献热心!
把查看手册形成条件反射!

TOP

19楼的代码似是而非
又没有处理转义符号
不能作为for命令语法分析的参考

把cmd内部命令理解为函数未尝不可
但不要生硬套用函数模型来强解命令行分析

for和if不是关键字而是命令
官方文档提到的关键字
是f ...
qzwqzw 发表于 2011-5-26 21:29

似乎一步一步地明朗化了

TOP

19楼的代码似是而非
又没有处理转义符号
不能作为for命令语法分析的参考

把cmd内部命令理解为函数未尝不可
但不要生硬套用函数模型来强解命令行分析

for和if不是关键字而是命令
官方文档提到的关键字
是for命令中的in、do、eol、skip、delims、tokens、usebackq
以及if命令中的not、exist、defined、errorlevel
诸如此类批处理命令中组成命令语法的固定字词
关键字本身不应该具有任何解析上的含义

关于预处理我倾向于这样定义
在批处理中开启echo on后语句所显示的形态即预处理的结果
这个过程cmd对所有语句是统一处理的
此后cmd对语句的语法分析会针对不同命令而有不同
比如各命令对于命令分隔符的处理牵扯到语法分析而各有差异
因此不应算作cmd预处理的范畴
天的白色影子

TOP

所有内部命令都相当于是一个函数好吧
命令行参考:hh.exe ntcmds.chm::/ntcmds.htm
求助者请拿出诚心,别人才愿意奉献热心!
把查看手册形成条件反射!

TOP

关键字又是什么概念?如果能弥补“函数论”的缺陷,我不介意叛变...

TOP

for、if应该的确是“关键字”而非一般命令,
预处理时就把参数传给它们了,从而它们也进行并影响预处理,而不是等cmd.exe先预处理完了再调用for。
上面提到的把非空格分隔符替换为空格,就是一个例子:
bat中 for %%a in (a;echo) do echo a;echo
预处理后是这样的:
for %a in (a echo) do echo a;echo
命令行参考:hh.exe ntcmds.chm::/ntcmds.htm
求助者请拿出诚心,别人才愿意奉献热心!
把查看手册形成条件反射!

TOP

23# applba


我总结一下:
运行前的预处理,如果有可用的(即没有被转义)分隔符(如空格、逗号等)是会进行参数分割的。
如果没有可用分隔符,把第一个空格后的所有字符串作为一个整体参数传递。
这个过程是cmd .exe来完成的。

有些命令运行时会再次识别转义后的特殊字符,并再次启动解释工作。
比如call会再次识别转义后的%、^、空格等。
for也会再次识别转义后的空格等

TOP

命令行的POSIX规范:
以一个横杠开头的为选项。
如果不带参数的话,多个选项可以写在一个横杠后面。如-abc与-a -b -c的含义相同。
选项名是单字符的英文字母或者数字。
某些选项是带参数的。
选项和它的参数既可以分开写也可以在一起,grep选项中的 -A 10 与 -A10都是合乎规范的。
选项参数写在非选项参数之前。
如果一个参数只是两个横杠--,那么它会结束所有的选项,所有跟在它后面的参数都被视作非选项,即使它们前面有一个横杠。
一个单横杠-被解释为普通的非选项参数,通常它用来表示对标准输入和输出流的输入或者输出。
选项之间可以是任意顺序,也可多次出现,由程序负责对此进行解释。

微软似乎喜欢和POSIX对着干。
Windows下满足这一规范哪怕是其中几条的命令寥寥无几,xcopy、findstr等命令的参数可以写在一起,这样看来for /f 勉强也算上吧。
命令行参考:hh.exe ntcmds.chm::/ntcmds.htm
求助者请拿出诚心,别人才愿意奉献热心!
把查看手册形成条件反射!

TOP

要说的是,那段c代码跟cmd的for完全没关系,只是一段再普通不过的代码,打印出所有的命令行参数。
只是为了试验对分隔符转义后,可不可以让多个参数被整体当作成一个参数。
命令行参考:hh.exe ntcmds.chm::/ntcmds.htm
求助者请拿出诚心,别人才愿意奉献热心!
把查看手册形成条件反射!

TOP

个人认为/f开关是for所有开关中最重要的一个,对于新手甚至部分老手要掌握这个/f开关的所有参数及其用法是有一定难度的。。。

关于eol,usebackq,skip,tokens,delims这五个/f开关下的参数,记得cn-dos的9527有一篇 ...
batman 发表于 2011-5-25 19:30

基于for的参数不需要空格分隔的理论基础,老兄这说法也大有问题,而且哪怕用上空格来分隔,似乎也不惧:
  1. @echo off
  2. for /f "delims=, tokens=1,2 eol=e skip=1" %%a in ('
  3. "echo skip&echo eol&echo 显 示,不显示"
  4. ') do echo %%a
  5. pause
复制代码
该显示的仍然显示了,不该显示的也同样没有显示,并不因为“delims=,”后跟空格而造成误判。看来for对于参数的划分有点像cmd对于重定向的划分,虽然在cmd回显中看不到,但是我想,for对参数的划分应该也是和cmd同样的从预处理到执行的步骤:
1、转换分隔符为空格,如果不存在分隔符则自动加上空格(就像cmd会把“echo>nul 不显示”预处理成“echo 不显示 1>nul”一样)
2、读取参数#@!@@#¥!……

另外,顺便提一个疑惑,如果for真的是函数,如何解释for在语块中不能对其参数使用带有延迟性质的变量呢?

TOP

看得心慌,19楼的代码真的看懂了么?

那个for.exe命令行输入
  1. for.exe a=b=c x;,y 5678"\"\""" ....
复制代码
然后再输入
  1. for.exe /f delims=+ tokens=1-3 %a in ("fdf""dfd\"\"")do ^^echo %a
复制代码
体会下;

另外,cmd对代码预处理后的结果就是
在cmd开启echo on 后在屏幕上显示的结果;这个界定适合脚本也适合命令行;

我们看预处理做了哪些工作,用echo on的方法就行了,再做“批处理物理实验”就绕弯路了;

TOP

还有一个特殊的地方是
-> for.exe tokens^=1-3
argv[0]: `for.exe`
argv[1]: `tokens=1-3`

-> test.bat tokens^=1-3
%0: `test.bat`
%1: `tokens`
%2: `1-3`

同样的参数,程序和bat脚本竟然认为个数不同。而且不加转义符号结果一样。
看来是对合法分隔符的识别问题。
CMD会把分号、逗号、等号等都当作分隔符,但其他程序不这么认为。
命令行参考:hh.exe ntcmds.chm::/ntcmds.htm
求助者请拿出诚心,别人才愿意奉献热心!
把查看手册形成条件反射!

TOP

运行前的处理就是预处理。
从上面例子看for和if会影响预处理的。
再结合前一个例子,按一般理解,for /f 的 "usebackq skip eol tokens delims"等选项必须用引号引起来,可能就是为了让它整体作为一个参数传递给for“函数”(就象路径中有空格时也需要引号引起来),但可能因为预处理的特殊对待,不用引号也行,方法是对分隔符加^进行转义。但这种方法对其他程序无效,就像没转义一样,参数个数还是实际那么多。
命令行参考:hh.exe ntcmds.chm::/ntcmds.htm
求助者请拿出诚心,别人才愿意奉献热心!
把查看手册形成条件反射!

TOP

返回列表