[新手上路]批处理新手入门导读[视频教程]批处理基础视频教程[视频教程]VBS基础视频教程[批处理精品]批处理版照片整理器
[批处理精品]纯批处理备份&还原驱动[批处理精品]CMD命令50条不能说的秘密[在线下载]第三方命令行工具[在线帮助]VBScript / JScript 在线参考
返回列表 发帖
把以前的东西帖出来,先啥都不说,你们自己看,仔细看。(可怜以前没人参与讨论)
  1. -> type for.c
  2. #include <stdio.h>
  3. int main(int argc, char *argv[])
  4. {
  5.     int i;
  6.     for(i=0;i<argc;i++)printf("argv[%d]: `%s`\n", i, argv[i]);
  7.     return 0;
  8. }
  9. -> gcc -o for.exe for.c
  10. -> for.exe /f tokens^=1-3^ delims^=^" %a in ("a"b"c") do echo %a-%b-%c
  11. argv[0]: `for.exe`
  12. argv[1]: `/f`
  13. argv[2]: `tokens=1-3`
  14. argv[3]: `delims= %a in (abc) do echo %a-%b-%c`
  15. -> type for.bat
  16. @for.exe /f tokens^=1-3^ delims^=^" %%a in ("a"b"c") do echo %%a-%%b-%%c
  17. -> for.bat
  18. argv[0]: `for.exe`
  19. argv[1]: `/f`
  20. argv[2]: `tokens=1-3`
  21. argv[3]: `delims= %a in (abc) do echo %a-%b-%c`
  22. -> for.exe tokens^=1-3
  23. argv[0]: `for.exe`
  24. argv[1]: `tokens=1-3`
  25. -> test.bat tokens^=1-3
  26. %0: `test.bat`
  27. %1: `tokens`
  28. %2: `1-3`
复制代码
命令行参考:hh.exe ntcmds.chm::/ntcmds.htm
求助者请拿出诚心,别人才愿意奉献热心!
把查看手册形成条件反射!

TOP

不是说for和if是“关键字”吗?难道是微软内部泄露出来的?
  1. -> type test.bat
  2. @prompt -$G$S
  3. echo a;echo
  4. for %%a in (a;echo) do echo a;echo
  5. echo for %%a in (a;echo) do echo a;echo
  6. rem if a;echo==a;echo echo a;echo
  7. if a==a;echo echo a;echo
  8. echo if a;echo==a;echo echo a;echo
  9. @echo\&pause
  10. -> test.bat
  11. -> echo a;echo
  12. a;echo
  13. -> for %a in (a echo) do echo a;echo
  14. -> echo a;echo
  15. a;echo
  16. -> echo a;echo
  17. a;echo
  18. -> echo for %a in (a;echo) do echo a;echo
  19. for %a in (a;echo) do echo a;echo
  20. -> rem if a;echo==a;echo echo a;echo
  21. -> if a == a echo echo a;echo
  22. echo a;echo
  23. -> echo if a;echo==a;echo echo a;echo
  24. if a;echo==a;echo echo a;echo
  25. 请按任意键继续. . .
复制代码
把分号换成逗号、等号效果一样。

可见预处理时对for、if的“参数”有特殊对待,会先把非空格分隔符统一处替换成空格。而for、if引导的命令中的分号、逗号、等号等不改变。
命令行参考:hh.exe ntcmds.chm::/ntcmds.htm
求助者请拿出诚心,别人才愿意奉献热心!
把查看手册形成条件反射!

TOP

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

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

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

TOP

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

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

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

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

TOP

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

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

被你发现了,我故意取名为for.exe,就是为了混淆一下,看看大家会不会仔细分析我帖的那些代码。
我后面也说了,这个for.exe与cmd的for完全没有关系。

通过它对参数的解析来对比,再结合for /f 常规用法是需要引号把参数括起来(可能的目的是整体当成一个参数),主要论点是如果不用引号,而是把分隔符转义,for /f 的各个函数对for来说是不是整体作为一个参数。如果这个观点成立,则进一步得出for、if也要参与预处理的观点。
再帖一下:
bat中 for %%a in (a;echo) do echo a;echo&findstr /v ; C:\boot.ini
预处理后是这样的:(不用说,打开回显即可看到)
for %a in (a echo) do echo a;echo  & findstr /v ; C:\boot.ini
注意,括号中的分号被替换成了空格,do后面命令中的则没变。
命令行参考:hh.exe ntcmds.chm::/ntcmds.htm
求助者请拿出诚心,别人才愿意奉献热心!
把查看手册形成条件反射!

TOP

返回列表