[新手上路]批处理新手入门导读[视频教程]批处理基础视频教程[视频教程]VBS基础视频教程[批处理精品]批处理版照片整理器
[批处理精品]纯批处理备份&还原驱动[批处理精品]CMD命令50条不能说的秘密[在线下载]第三方命令行工具[在线帮助]VBScript / JScript 在线参考
返回列表 发帖
  1. @echo off
  2. (for /f "tokens=3,5 delims==> " %%a in (1.txt) do for /f "tokens=1,2" %%c in ("%%~a %%~b") do echo %%c,%%d,1)>2.txt
复制代码

TOP

3# applba
delims不能用引号作为分隔符

4# Hello123World
这个确实忘了,因为原先是分两步的,简化后忘了统一起来。

TOP

呀,回帖时忽然有了个猜想,验证下竟然真的可以,看来可以推翻delims不能用"作为分隔符的观点了:
  1. @echo off
  2. for /f tokens^=1*^ delims^=^" %%a in ("sd"z"vc") do echo %%b
  3. pause
复制代码
5

评分人数

TOP

1.为什么你的条件引号都没有也能行?
2.结果是z"vc  ,这说明"并不是真的作为分隔符在起作用。结果2是我错了,*会连同分隔符一起显示。
Hello123World 发表于 2011-5-21 14:53

1,以前一直惯性思维,没想过引号是的真实目的,我想for可能只能读取一个参数,而""就是把多个参数合并成一个参数的媒介,同时兼具转移作用,避免=被当成语句中的分隔符,所以就去掉引号,用转义来达到它的效果
2,没细看我的代码吗?
1

评分人数

TOP

耶,我终于也有技术创新了...

TOP

各位大大能解释一下这句吗?
(for /f tokens^=2^,4^ delims^=^" %%a in (test.txt) do echo %%a,%%b,1)>2.txt
一般看到的都是
for /f "tokens=1,delims=" 变量 in(文件名) do echo 变量
但是在这里怎么多加了2个 ...
fengyun530 发表于 2011-5-22 11:03



我的理解是(马后炮...)习惯上为for /f命令的各种参数加引号是为了转义“=”、“ ”等会被误认为分隔符的参数内容,for /f可能只能接受一个参数,所以useback可以不加引号:
for /f useback %%a in ("te st.txt") do echo %%a
但是却不能与其他参数不使用"来直接联用,而且其他带=或其他有分隔符意义字符的参数若不用"或者^来转义就直接使用,运行时“tokens=1,4”会被cmd理解成“tokens 1 4”,这当然会出错,但是我们可以通过用^转义的方法来代替引号的作用,原理就像
“for /f %%a in ('dir /b^|sort') do echo %%a”
等同于
“for /f %%a in ('"dir /b|sort"') do echo %%a”
一样。

TOP

而且利用for /f的特性也可以实现变量延迟哦:
  1. @echo off
  2. (
  3. echo %random%
  4. for /f %%a in ('echo %%random%%') do echo %%a
  5. pause
  6. )
复制代码
这是for /f的运行机制决定的

TOP

19# applba

以百分号为分隔符要考虑到预处理的因素:
... delims=%% ...

TOP

回复 22# fanfande


    详见《[系列教程]批处理for语句从入门到精通[20101225更新]》:http://bbs.bathome.net/thread-2189-1-1.html
tokens 是以 delims 指定的字符集为分隔符,对输入的单行或多行内容进行划分,并取在 tokens 中指定的第 n 节,而其后引用的参数则收 tokens 影响,如果要用令牌(%%a、%%b 等)对指定的某几节进行选取,必须在 tokens 中声明改节位置。
    比如:
  1. for /f %%a in ("测试 test") do echo %%%%a=%%a   %%%%b=%%b
  2. ::在for 中除了 usebackq 和 skip 外所有开关均有默认参数,上面这句貌似啥也没设置,其实默认为:"eol=; tokens=1 delims=[tab制表符][空格]"
  3. ::而因为在隐藏的默认参数中,tokens 仅指定了 1,所以只分配第一节内容给了 %%a,而没有分配任何内容给 %%b
  4. for /f "tokens=1,2,4-5 delims=诗《》:" %%a in ("唐诗经典:(插入广告)《长恨歌》白居易") do echo 由 %%a 代诗人 %%d 所著的 %%c 是一部 %%b 。
  5. ::delims 指定了四个分隔符,tokens 以此为据,指定要取第1、2、4、5 节
  6. ::这里的 1,2 表示第 1 和 2 节,而 4-5 表示 4 到 5 节(在取连续多节的时候是很有效的简写,此处仅为示例)
  7. ::而要注意的是,因为此处未在 tokens 中指定第 3 节,故 %%c 跳过第三节,直接与已被声明的第 4 节对应,%%d 则紧随其后,与第 5 节对应。
  8. for /f "tokens=2* delims=-" %%a in ("当前日期-北京时间-2011-11-24") do echo %%b
  9. ::tokens 中 * 除非是唯一参数,否则必须跟在某个数字后面,以声明其位置。
  10. ::在 tokens 中指定了某一节后我们可以不引用它,但是他会占用一个对应位置的令牌
  11. for /f "tokens=* delims=0" %%a in ("000001234000") do echo %%a
  12. ::将第一节与其后内容作为一个整体,去掉前缀的所有分隔符 0
  13. ::"tokens=*" 与 "delims=" 的区别就在于此,前者将删除第一节之前的所有分隔符取其后内容,而后者则是不指定分隔符所以整行文本作为一节内容输出。
复制代码
需要注意的是,tokens 的范围从 1~32,其中能明确指定第几节的是 1~31 节,第 32 个只能是 *,无法一次性取得。
我们写在 in 前面的那个令牌代表所取的第一节,其后令牌往下类推,比如当第一个令牌为 %%a 时,第 2-3 节为 %%b 和 %%c,当第一个令牌被设为 %%b 时,第 2-3 节为 %%c 和 %%d,依此类推,不过大小写字母是不同的,原因见下文。
当然可能有人会疑惑了,字母才 26 个,要怎么设定为首的令牌怎么取满 1-31* 中所有节呢?其实这不成问题,因为 for 中的令牌名是以 unicode 编码形式出现的,unicode 编码顺序就是令牌的排序,而几乎所有 unicode 字符均可作为令牌名
在 hanyeguxing 的 《Windows 代码页与字符顺序》:http://bbs.bathome.net/viewthread.php?tid=12329 中声明:
第二类如 set 、dir 、for 等,按 UNICODE 编码顺序排列,不使用 sortkey.nls 顺序。

而 plp626 的 《[讨论]批处理for命令的参数和扩展特性》:http://bbs.bathome.net/viewthread.php?tid=12500 中亦有实例证明:
  1. :: cmd命令行下粘贴如下代码
  2. :: "老" 到 "耣" 的unicode编码(连续地)为 "8001" 到 "8023"
  3. set ss=1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32
  4. for /f "tokens=1-31" %老 in ("%ss%")do @echo %老 %耂 %考 %耄 %者 %耆 %耇 %耈 %耉 %耊 %耋 %而 %耍 %耎 %耏 %耐 %耑 %耒 %耓 %耔 %耕 %耖 %耗 %耘 %耙 %耚 %耛 %耜 %耝 %耞 %耟 %耠 %耡 %耢 %耣
复制代码
而在 0x20~0x7f 范围内(小于 0x7f 都是单字节字符,超过此范围就是由双字节组成的宽字符)究竟有哪些字符可用,我也做过相应测试,证明除了某些字符由于预处理的原因无法使用以外,其余所有字符均可作为令牌名出现。

TOP

返回列表