Board logo

标题: [文件操作] 【讨论】这是不是又是for的一个bug [打印本页]

作者: batman    时间: 2011-5-28 12:27     标题: 【讨论】这是不是又是for的一个bug

本帖最后由 batman 于 2011-5-28 13:05 编辑

前言:
  这个问题是昨天晚上帮人解决一个文件处理问题时碰到的,害我查错查了一个多小时,最后发现是for /r的问题,现用代码将问题模拟出来,供大家讨论:
  1. @echo off&setlocal enabledelayedexpansion
  2. set "str=temp\"
  3. for /l %%a in (1,1,10) do set "str=!str!%%a\"
  4. if not exist !str! md !str!
  5. for /l %%a in (1,1,100) do cd.>!str!%%a.txt
  6. for /r temp %%a in (*.txt) do (
  7.     echo "%%~dpa"
  8.     for /r "%%~dpa" %%b in (*.txt) do echo "%%b"&pause
  9.   echo ok
  10.     for /r "%cd%\temp\1\2\3\4\5\6\7\8\9\10\" %%b in (*.txt) do echo "%%b"&pause
  11. )
  12. :: 将上面两个&pause去掉就可删除所创建的环境
  13. if exist temp rd /s /q temp
复制代码
  运行这个代码在我本机上的显示如下:

"D:\批处理\test\temp\1\2\3\4\5\6\7\8\9\10\"
ok
"D:\批处理\test\temp\1\2\3\4\5\6\7\8\9\10\1.txt"
请按任意键继续. . .请按任意键继续. . .


  按道理显示应为:

"D:\批处理\test\temp\1\2\3\4\5\6\7\8\9\10\"
"D:\批处理\test\temp\1\2\3\4\5\6\7\8\9\10\1.txt"


  如果for /r "%%~dpa" %%b in (*.txt) do echo "%%~dpb"&pause这句正常运行了,那么程序会在这个pause停住,而下面的ok不会显示出来,但实际上却是在for /r "%cd%\temp\1\2\3\4\5\6\7\8\9\10\" %%b in (*.txt) do echo "%%b"&pause上停住了(ok明显显示出来了),这就说明,第一个for /r没有得到正常运行,那么是不是因为目录级数太多了%%~dpa在for /r 中不能扩展为正确的路径啊?大家不妨展开思考和讨论。。。

ps:就是在回这个贴遇到的问题:http://www.bathome.net/thread-12539-1-1.html,最后将for /r改成for %%b in ("%%~dpa*.txt") do ..才解决问题
作者: CrLf    时间: 2011-5-28 12:44

不懂,试了试改成这样也是一样没反应:
  1. for /r %%b in ("%%~dpa*.txt") do echo "%%b"&pause
复制代码

作者: batman    时间: 2011-5-28 12:45

本帖最后由 batman 于 2011-5-28 12:47 编辑

改成这样就可以了:
  1. for %%b in ("%%~dpa*.txt") do echo "%%b"&pause
复制代码

作者: batman    时间: 2011-5-28 12:47

2# zm900612
楼上是不是笔误了,有这样的语法吗?
作者: CrLf    时间: 2011-5-28 12:55

本帖最后由 zm900612 于 2011-5-28 12:56 编辑

4# batman

原来是是语法不对
不是笔误,是我太少用for /r,没什么了解,以为可以这样用
作者: plp626    时间: 2011-5-28 13:14

前言:
for /r "%%~dpa" %%b in (*.txt) do echo "%%b"&pause
[/url]


%%~dpa作为for/r 开关的选项部分参数,在预处理时被读取固定。。。
这和
for /f "delims=%%a" %%b in (".....")do .... 属同一问题:


http://www.bathome.net/viewthrea ... romuid=353#pid80513
作者: batman    时间: 2011-5-28 13:37

运行下面的代码:
  1. @echo off
  2. for %%a in ("%cd%") do (
  3.     echo "%%~dpa"&pause
  4.     for /r "%%~dpa" %%b in (*) do echo "%%b"&pause
  5. )
复制代码
  第一个pause处正确显示%%~dpa对路径的扩展,回车后程序退出,for /r没执行,在cmd中运行也没看到任何报错信息。改成%%~da或%%~pa都是一样的情况,因此,我们可以得出初步结论如下:

  for /r语句中的path是不能用%%~da %%~pa %%~dpa这样的形式来扩展

ps:个人猜测for /r不识别~字符。。。
作者: batman    时间: 2011-5-28 13:53

  1. @echo off
  2. for /r "~" %%a in (*) do echo %%a&pause
复制代码
  成功显示信息(实际创建了~目录)
  1. @echo off
  2. for /r "%%~" %%a in (*) do echo %%a&pause
复制代码
  一闪而过(实际创建了%%~目录)

  从此看来不是不识别~字符的问题,真的是预处理的问题,cmd首先将%%~扩展为~变量去寻找其值,而~字符是不能用来做为变量字符的,所以造成了我遇到的问题。唉,真的要把预处理吃透才能避免再出现这样的问题了!
作者: CrLf    时间: 2011-5-28 15:41

%%~dpa作为for/r 开关的选项部分参数,在预处理时被读取固定。。。
这和
for /f "delims=%%a" %%b in (".....")do .... 属同一问题:


http://www.bathome.net/viewthrea ... age=4&fromuid=3 ...
plp626 发表于 2011-5-28 13:14

晕,把这茬忘了
作者: CrLf    时间: 2011-5-28 15:44

@echo off
for /r "~" %%a in (*) do echo %%a&pause
  成功显示信息(实际创建了~目录)
@echo off
for /r "%%~" %%a in (*) do echo %%a&pause
  一闪而过(实际创建了%%~目录)

  从此看来不是不识 ...
batman 发表于 2011-5-28 13:53

可为什么我这里可以识别?
  1. @echo off
  2. md %%~
  3. cd.>%%~\test.txt
  4. for /r "%%~" %%a in (*) do echo %%a&pause
复制代码

作者: 随风    时间: 2011-5-28 17:54

for 的 in 前面不能用 %%i !var! 这样的变量,这个以前讨论过的呀。。。
作者: regabc    时间: 2011-5-28 17:58

哈哈,遇到有挑战性的问题了。
作者: applba    时间: 2011-5-28 20:07

我懂了,是不是 for /r的 in (set) 中的内容处理发生在迭代之前,就是说(set)中的内容处理时 %%i还是空的。
作者: CrLf    时间: 2011-5-28 20:16

13# applba

请打开回显看这段代码:
  1. for %%a in (@) do for /f "tokens=1* delims=%%a" do %%b in ("123@234a345") do echo %%a----%%b
  2. pause
复制代码
我现在才明白“for记住了参数”和“for的参数只参与一次预处理”这两种说法的区别
作者: techon    时间: 2011-5-29 00:35

楼上多打了个 do
for %%a in (@) do for /f "tokens=1* delims=%%a" do
。。。




欢迎光临 批处理之家 (http://bbs.bathome.net/) Powered by Discuz! 7.2