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


我用2235行的厚黑学全集试了试(题外话,下载回来都木油看过,原来这玩意就是用来测试的...),结果相差无几
for /f:
  1. @echo off
  2. echo %time%
  3. (
  4.     for /f "delims=" %%a in (test.txt) do (
  5.         set str=%%a
  6.         setlocal enabledelayedexpansion
  7.         echo,!str: =_!
  8.         endlocal
  9.     )
  10. ) >test_2.txt
  11. echo %time%
  12. pause
复制代码
回显:
  1. 0:55:30.77
  2. 0:55:32.83
  3. 请按任意键继续. . .
复制代码
set /p:
  1. @echo off
  2. echo %time%
  3. (
  4.     for /l %%a in (1 1 2235) do (
  5.         setlocal enabledelayedexpansion
  6.         set /p str=
  7.         echo,!str: =_!
  8.         endlocal
  9.     )
  10. ) <test.txt >test_1.txt
  11. echo %time%
  12. pause
复制代码
回显:
  1. 0:55:34.07
  2. 0:55:36.37
  3. 请按任意键继续. . .
复制代码
结果是 2.04:2.30,差距约为十分之一...视实际情况而定吧,毕竟遍历方式以及来源的异同决定了这两种用法有各自适用范围~

TOP

很好,很强大!!!
庆贺又一bathome原创技术的诞生!!!
***共同提高***

TOP

本帖最后由 mxxcgzxxx 于 2011-7-19 08:45 编辑

从特殊字符方面来说还是有很大区别的
  1. !@#~#$%^&*()_+-={}|":?><;'\`"~!@#$%^&*()_+|":?><
复制代码
用SET/P和FOR/F分别读取并输出
  1. @echo off
  2. setlocal enabledelayedexpansion
  3. (
  4.     for /l %%a in (1 1 1) do (
  5.         set/p echo=
  6.         echo.!echo!
  7.         )
  8. ) <1.txt >2.txt
  9. for /f "delims=" %%1 in (1.txt) do (
  10.        set "str=%%1"
  11.        echo !str!
  12.        )>>2.txt
复制代码
结果
  1. !@#~#$%^&*()_+-={}|":?><;'\`"~!@#$%^&*()_+|":?><
  2. ?><;'\`"~?><
复制代码
说明,如果在有特殊字符的情况下,SET/P更加合理而简便
1

评分人数

世界上没有学不会的知识,也没有想得到却做不到的事!

TOP

本帖最后由 mxxcgzxxx 于 2011-7-19 09:39 编辑
  1. @echo off
  2. setlocal enabledelayedexpansion
  3. (
  4.        set/p a=
  5.        set/p b=
  6.        set/p c=
  7.        echo.!a!
  8.        echo.!b!
  9.        echo.!c!
  10.        )<1.txt >2.txt
复制代码
这样子是一次性获取头三行信息,
利用这个可进行隔行获取
  1. @echo off
  2. (
  3.      for /l %%1 in (1 1 10 ) do (
  4.        setlocal enabledelayedexpansion
  5.        set/p 偶数行=
  6.        set/p 奇数行=
  7.        echo.!偶数行!>>2.txt
  8.        echo.!奇数行!>>3.txt
  9.        endlocal
  10.        )
  11. )<1.txt
复制代码
测试了多种组全发现,SET/P可以全文吸收一个字符都不错,
但无法跳过空行是一个优点也是一大问题
世界上没有学不会的知识,也没有想得到却做不到的事!

TOP

本帖最后由 zm900612 于 2011-7-19 09:53 编辑

18# mxxcgzxxx

可以用开闭变量延迟来提升对特殊字符的兼容性,但是我没测试过这个动作对效率的影响:
  1. @echo off
  2. for /f "delims=" %%1 in (1.txt) do (
  3.        endlocal
  4.        rem 此时关闭变量延迟以免 %%1 中含有 ! 致错
  5.        set "str=%%1"
  6.        setlocal enabledelayedexpansion
  7.        rem 此时打开变量延迟以即时读取变量
  8.        echo !str!
  9. )>>2.txt
复制代码
另外,要跳过的行可以不赋值...三行一周期,获取周期中的首尾两行:
  1. (@echo off
  2. for /l %%a in (1 1 12) do (
  3.     set .1=
  4.     set .2=
  5.     set /p .1=
  6.     set /p=
  7.     set /p .3=
  8.     echo;!.1!
  9.     echo;!.2!
  10. ))<%0
  11. pause
复制代码
确实,不跳过空行既是优点也是缺点,另外还有两个不知道是优点还是缺陷的特性,一是 set /p 接收到空输入时不会清空该变量原有值,二是无法一步到位地完成变量赋值、加前后缀、切割等等复杂动作。

TOP

12# mxxcgzxxx


刚刚又去向无所不能的寒夜版主请教,我们原来以为 pause 会把紧随其后的 0D 0A 整个吞掉(因为曾经尝试用 pause 取换行符无果),但是12楼的代码举了个反例,这实在让我想不通,难道 pause 能提前判断下一行是否非空、当下一行不为空时则只吞 0D 吗?

后来找到了一个更为合理的假设,那就是 pause 本来就只吞碰到的第一个字符,此处的第一个字符也就是回车符 0D,而 set /p 继续接收第二行输入时接到了 0A ( 0D 0A,所以出现了换行效果。但是当第二行也是空行时,set /p 接收到的就是 0A 0D 0A,我们猜测 set /p 默认不会将单纯的换行符 0A 设为变量,所以 set /p 赋值为空。

做了个实验证明这一点:
  1. @echo off
  2. (for /l %%a in (1 1 10) do (
  3. pause>nul
  4. pause>nul
  5. rem 用两个pause测试,看究竟是否吞了两组 0D 0A,如果 pause 是吞整个 0D 0A,那结果应该不会出现空行或者带换行符的变量
  6. set /p .%%a=))<%0
  7. set.
  8. pause
复制代码
结果果然空了一行,证明每个 pause 确实只是取走紧随其后其后的那个字符,而非能够“预知”下一行的内容。

TOP

本帖最后由 mxxcgzxxx 于 2011-7-19 15:49 编辑

21# zm900612
听起来是这个理,但下面这个情况怎么解释呢?
  1. @echo off
  2. (for /l %%a in (1 1 10) do (
  3. pause>nul
  4. rem 用两个pause测试,看究竟是否吞了两组 0D 0A,如果 pause 是吞整个 0D 0A,那结果应该不会出现空行或者带换行符的变量
  5. set /p .%%a=))<%0
  6. set.>1.txt
  7. pause
复制代码
输出的1.txt为
.1=echo off
.4=for /l %%a in (1 1 10) do (
.5=ause>nul
.6=em 用两个pause测试,看究竟是否吞了两组 0D 0A,如果 pause 是吞整个 0D 0A,那结果应该不会出现空行或者带换行符的变量
.7=et /p .%%a=))<%0
.8=et.>1.txt
.9=ause

按理应该是下面这样取值的啊,为什么到3行出错了?然道说第三行的 0D 0A 可以用两次
@echo off 0D 0A
0D 0A
0D 0A
0D 0A
(for /l %%a in (1 1 10) do ( 0D 0A
pause>nul0D 0A
rem 用两个pause测试,看究竟是否吞了两组 0D 0A,如果 pause 是吞整个 0D 0A,那结果应该不会出现空行或者带换行符的变量0D 0A
set /p .%%a=))<%0 0D 0A
set.>1.txt 0D 0A
pause 0D 0A

.1=echo off
.2=0A 0D 0A
.3=0A
for /l %%a in (1 1 10) do (
.4=ause>nul
...
世界上没有学不会的知识,也没有想得到却做不到的事!

TOP

有半个换行符的值写入文本后会出现一个像退格符的黑块,但我发不上论坛,
可以对TXT文本进行复制并写到批处理里面,很好用也
但无法通过变量截取的方式获得有点可惜!
世界上没有学不会的知识,也没有想得到却做不到的事!

TOP

22# mxxcgzxxx


诡异,测试后发现一次循环中只有一个 pause 时,连续空行数以一种奇怪的规律影响着变量的赋值:当连续空行数量为1、4、6、8...等数字时,会出现行首带有换行符的变量,这究竟是什么原因导致的呢...我也想不通了

TOP

本帖最后由 mxxcgzxxx 于 2011-7-19 17:05 编辑

24# zm900612


那可以这样理解吗? 0D 0A 和0A 0D 都可以起到结束SET/P的输入过程
三行空行时
0D 0A
0D 0A
0D 0A
第一个0D被吃  SET/P得到0A 0D (强行终结)
第二个0A被吃   SET/P得到0D 0A (完整)
这样还能解释为什么三个空行被赋值两次
0A 0D 的组合有没有代表什么?
5个空行情况:
吃 ---- 留
0D---0A| 0D
0A|---0D  0A|
0D---0A| 0D
0A|---文本,所以正常不换行

以此类推,基本都合理了
1空行:0A 换行文本
2空行:完整文本
3空行:文本少头一字符
4空行:0A 换行文本
5空行:完整文本
。。。三个空行一个循环,所以:
1,4,7,10。。。为换行文本
2,5,8,11。。。为不少字的完整文本
0,3,6,9。。。为少头一字符的文本

刚才测试了下,完全符合这个规律!
1

评分人数

    • zm900612: 妙!很有可能如此PB + 5 技术 + 1
世界上没有学不会的知识,也没有想得到却做不到的事!

TOP

本帖最后由 CrLf 于 2011-7-21 16:23 编辑

25# mxxcgzxxx


好!确实很有可能,测试代码如下:
  1. @echo off
  2. set x0a=^
  3. ::空行请自行添加
  4. for /f %%a in ('copy /z %~s0 nul') do set x0d=%%a
  5. cmd /v:on /c echo abc!x0a!!x0d!123!x0a!!x0d!>1.txt
  6. (for /l %%a in (1 1 10) do set /p .%%a=)<1.txt
  7. set.
  8. pause>nul
复制代码
证明确实是以三行为一周期(汗一个,早先对此的测试结果是忘了加上被换行的那一行的,所以当时测试所得的周期很没有规律...误导人啊误导人),而且很有可能确实是像老兄说的那样,只要碰到一组 0D 0A,无论它们字符顺序如何,都能结束 set /p 的输入行为。

可用如下代码进行验证:
  1. @echo off&setlocal enabledelayedexpansion
  2. set a=^
  3. (for /f %%a in ('copy /z %0 nul') do set b=%%a
  4. set<nul /p=赋值成功!a!!b!赋值失败)>1.txt
  5. set /p e=<1.txt
  6. echo !e!
  7. pause
  8. echo d|debug 1.txt
  9. ::如果未出现赋值失败的字眼则代表 0A 0D 成功地结束了 set /p 的输入,结果证明确实如此
复制代码
越来越完善了

TOP

本帖最后由 mxxcgzxxx 于 2011-7-21 16:50 编辑

用提取的换行符玩下,虽然不知实用性在哪方面可以应用?
因为论坛会吃单空格行,所以我使用:号
  1. :
  2. @echo off
  3. ::获取0A换行符
  4. (pause>nul&set /p a=)<%0
  5. echo 你好%a%我在哪?
  6. pause>nul
复制代码
由于半个换行让“我在哪?”进行了无间道,不存在的东西
但开了变量延时后就不一样了
  1. :
  2. @echo off
  3. setlocal enabledelayedexpansion
  4. ::获取0A换行符
  5. (set/p=&pause>nul&set /p a=)<%0
  6. echo 你好!!a!我在哪啊?!a!你也不知道吗?!a!真是可惜……
  7. pause>nul
  8. set "b=123!a!456!a!789"
  9. echo !b!
  10. pause>nul
复制代码
效果不是太理想但也很好了,一次三行内容,就是后面的每行多一个符号,可以加个退格符就可以了!!
而且可以通过赋值传达给别的函数,但一定要开变量延时和加上一个退格符!

我也搜索了论坛,应该来说这个方法是快而简便获取换行符的方法,
又一个新技术诞生了哈!
  1. :
  2. @echo off
  3. setlocal enabledelayedexpansion
  4. ::获取0A换行符
  5. (pause>nul&set /p a=)<%0
  6. ::通过赋值用退格符将换行符后的空格修整得到完整实用的换行符
  7. set "b=!a!"
  8. echo !b!123456!b!789
  9. pause>nul
复制代码
世界上没有学不会的知识,也没有想得到却做不到的事!

TOP

回复 27# mxxcgzxxx


    其实我有些混乱了,你的代码的意思是这样么?
  1. (pause>nul&set /p a=)<%0
复制代码
利用批处理开头来获取换行字符和空格字符
  1. set "b=!a!"
复制代码
换行+空格+退回字符=换行+不会再退回的退回字符=完整实用的换行符?

就达成了0d 0a组合的目的?
为何批处理不适合做界面
为何随风讨厌call命令
http://bbs.bathome.net/thread-4482-1-10.html

TOP

这个真的是新发现,竟然还支持嵌套,看来多个文件合并也可以了
  1. @echo off
  2. (set/p a1=
  3.    (set /p b1=
  4.    set /p b2=
  5.    )<bb.txt
  6. set/p a2=)<aa.txt
  7. set a
  8. set b
  9. pause
复制代码

TOP

回复 30# netbenton


版主请帮忙看看这个合并文件时处理特殊字符的问题吧
http://bbs.bathome.net/thread-13735-1-1.html

TOP

返回列表