Board logo

标题: [文件操作] [分享]批量文本重定向输出的新方案 [打印本页]

作者: qzwqzw    时间: 2010-5-3 17:59     标题: [分享]批量文本重定向输出的新方案

传统方案不用多说了
老老实实一个Echo一个重定向就可以了

后来发展出的方案则是分组输出
(for /l %%i in (1,1,10000) do echo string)>test1.log
这个方案的优点也不用多说
文件打开次数减少
时间性能有了很大提升

现在有一种新方案
使用二次重定向
cd. >con 3>test2.log
for /l %%i in (1,1,10000) do echo string
cd. >con 4>con

与方案2相比
文件打开次数是一致的
优点是在代码中出现多条输出指令时
不需要进行语句分组
也就不需要过多的预处理和启用变量延迟了

缺点是在一个cmd进程中
同样的方法只能使用一次

只有在关闭cmd进程后文件才会关闭
所以一般需要使用cmd/c新建cmd进程来调用批处理

[ 本帖最后由 qzwqzw 于 2010-5-3 18:01 编辑 ]
作者: x9tiancmd    时间: 2010-5-3 18:41

楼主能说说,  3>*   4>*   是代表什么意思吗?
作者: qzwqzw    时间: 2010-5-3 20:18

重定向中的秘密(句柄备份)
http://www.bathome.net/viewthread.php?tid=2579
作者: sgaizxt001    时间: 2010-5-3 23:03

字看的懂,但意思看不懂
优点和缺点完全不懂,能否讲解一二,我苯
作者: qzwqzw    时间: 2010-5-4 08:06

多看,多用,多想
很快你就会明白的

我怕照我的思路说下去
反而让你更加弄不明白
作者: zjw767676    时间: 2010-5-4 14:41

多看,多用,多想
很快你就会明白的

说得再明白不去实际操作也很快会忘记的
感谢分享!!!!

[ 本帖最后由 zjw767676 于 2010-5-4 14:43 编辑 ]
作者: plp626    时间: 2011-5-25 11:42

本帖最后由 plp626 于 2011-5-25 11:47 编辑

以上两贴摘自:
http://baike.baidu.com/view/194921.htm
windows编程,俺真不懂。。。

=================================
如何生成控制台重定向标准的句柄的进程

http://support.microsoft.com/kb/190351
作者: qzwqzw    时间: 2011-5-25 11:46

本帖最后由 qzwqzw 于 2011-5-25 11:52 编辑

把老帖翻出来供自己学习
楼上好无良啊 ^_^

句柄的理解不需要那么复杂
cmd缺省具有10个可供I/O的句柄
可以理解为10个可以存放I/O文件或者设备地址的空间
从0到9依次编号

句柄0-2大量地被命令行程序用来输入输出信息
他们都缺省存放控制台设备con的地址
con可以理解为当前的命令行窗口
但它们的读写属性有所差异
句柄0的别名是标准输入,限定只可读
句柄1的别名是标准输出,限定只可写
句柄2的别名是标准错误,可读可写

句柄3-句柄9缺省是空的,也均可读可写
需要通过重定向或者句柄复制给它们赋值
目前未发现有命令行程序使用句柄3-9进行输入输出
所以这些句柄现在只在句柄备份领域有特殊的应用
作者: CrLf    时间: 2011-5-25 13:02

我觉得与其把>&和<&说成是复制句柄,不如说成是转移句柄,这样就可以解释下面这句为什么无法实现既输出到文本又输出到屏幕了
  1. echo test 3>1.txt 1>&c3
复制代码

作者: CrLf    时间: 2011-5-25 13:09

而“真空”句柄无法被转移的特性导致无法将经过句柄备份后的还原为初始状态(非nul的真空状态)
  1. @echo off>con 3>nul
  2. rem 尝试还原句柄3为“真空” 3>nul 5>&4
  3. echo 能看到下一句test吗? >con 3>con
  4. echo test
  5. pause
复制代码

作者: qzwqzw    时间: 2011-5-25 15:24

本帖最后由 qzwqzw 于 2011-5-25 15:29 编辑

12# zm900612
句柄转移的概念模型建立并不理想
echo test 3>1.txt 1>&3
完全可以用句柄复制模型简单解释
1、1.txt赋给句柄3
2、句柄3复制到句柄1
最终结果就是句柄1和句柄3都被赋为1.txt
echo的输出通过句柄1输出到文件1.txt
而句柄3因为echo命令根本不用它输出
所以不会有任何结果上的影响

其实重定向和管道也可以看作是句柄复制的一种特例
重定向是将文件或者IO设备的句柄复制给cmd的保留句柄
管道是将cmd的句柄1(标准输出)复制给句柄0(标准输入)

另外重申和明确一个概念
句柄在cmd中不仅仅是文件和设备的地址
它还包含了一些附加的属性
比如I/O相关的读写属性
所以句柄0是缺省只读的
句柄1是缺省只写的
句柄2是缺省可读可写的
而句柄复制的过程中
不仅复制了句柄中的文件或设备地址信息
也同时复制了包括IO属性在内的附加信息
作者: plp626    时间: 2011-5-25 16:53

  1. cmd /q /c for /f %a in ('"for /f %a in ('echo 5678')do echo %a"')do echo %a
复制代码
多了一层就抓不到,这是怎么回事:
  1. cmd /q /c for /f %a in ('"for /f %a in ('"for /f %a in ('echo 1234')do echo %a"')do echo %a"')do echo %a
复制代码

作者: plp626    时间: 2011-5-25 16:56

还有这个帖子:http://bathome.net/viewthread.php?tid=9139&highlight=doskey
  1. cd&doskey/history
  2. for /f "delims=" %a in ('doskey/history')do @echo %a
复制代码

作者: CrLf    时间: 2011-5-25 17:08

15# plp626


因为这样就有了两对引号,在语句的预处理中出错了
作者: CrLf    时间: 2011-5-25 17:11

14# qzwqzw


好吧,我又没把观念扭过来,我原来一直以为句柄重定向的是每个句柄输出的内容,而不是要定向到的设备,昨天老兄已经纠正了这个错误观点,但是我今天又搞混了
作者: CrLf    时间: 2011-5-25 17:20

cmd /q /c for /f %a in ('"for /f %a in ('echo 5678')do echo %a"')do echo %a多了一层就抓不到,这是怎么回事:cmd /q /c for /f %a in ('"for /f %a in ('"for /f %a in ('echo 1234')do echo %a"')do echo %a"' ...
plp626 发表于 2011-5-25 16:53
  1. cmd /q /c for /f %a in ('"cmd /q /c for /f %a in ('for^ /f^ %a^ in^ ('echo^ 1234'^)do^ echo^ %a')do echo %a"') do echo %a
复制代码

作者: plp626    时间: 2011-5-25 17:33

19楼,你测试了否? 我这里照样没法抓到。。
作者: CrLf    时间: 2011-5-25 17:37

测试的时候是没加cmd /q /c的,不过有回显,所以发贴的时候就在for内加了cmd /q /c,把它去掉就看到了:
  1. cmd /q /c for /f %a in ('"for /f %a in ('for^ /f^ %a^ in^ ('echo^ 1234'^)do^ echo^ %a')do echo %a"') do echo %a
复制代码

作者: plp626    时间: 2011-5-25 17:54

那次你那个引号的分隔符。。。
细想了下,还真是预处理的关系:
  1. cmd /q /c for /f %a in ('"for /f %a in ('for,/f,%a,in,^('echo,1234'^)do,echo,%a')do echo %a"') do echo %a
复制代码
但还在想其中缘由,,,
作者: plp626    时间: 2011-5-25 17:58

为什么空格在这里就不能再作为参数分割符,而要用逗号,分号或者等号?
  1. cmd /q /c for /f %a in ('"for /f %a in ('for=/f=%a=in=^('echo,1234'^)do=echo=%a')do echo %a"') do echo %a
复制代码

作者: plp626    时间: 2011-5-25 18:06

给空格加转义多此一举,这里主要是括号的原因:
  1. cmd /q /c for /f %a in ('"for /f %a in ('for /f %a in ^('echo,1234'^)do echo %a')do echo %a"') do echo %a
复制代码
参数分隔符在过程中仍旧还是:空格,制表符,逗号,分号,等号
作者: plp626    时间: 2011-5-25 18:09

原因来自括号匹配:
  1. cmd /q /c for /f %a in ('"for /f %a in ('for /f %a in ('echo,1234'^)do echo %a')do echo %a"') do echo %a
复制代码

作者: plp626    时间: 2011-5-25 18:29

本帖最后由 plp626 于 2011-5-25 18:52 编辑

可以这样理解for的二次预处理特性:
for ~ cmd内部的一个类似call的子过程。。。

这个内部子过程有/r /d /f 三个开关,有共同的do in 关键字,一对括号,有最多32个连续单字符名的内置变量
(相对call,若不shift则为10个);

/f 开关有eol,skip,usebackq,delims,tokens,5个关键字,他们作为/f开关的 “第一个参传递”

调用这个子过程的时候,参数分割符同call的参数分隔符;
作者: plp626    时间: 2011-5-25 18:40

我原来以为是for /f 的嵌套输出没有按预期输出,是不是和什么句柄有关。。。所以发了那样的疑问。。。

后面验证时和括号匹配有关。。。

遂把自己对for的理解一块放这里,好作为一个思考连贯的过程。。。

在我看来没有什么不会联系到一起的。。。
作者: batman    时间: 2011-5-25 18:46

27# qzwqzw
应楼主的要求,每人扣除1000分。。。

呵呵,先记着(缓期执行)。。。

两位兄弟研究的热情和精神让人佩服,但你们是不是也照顾下楼主的感受,另发贴讨论不是更好吗。。。
作者: CrLf    时间: 2011-5-25 22:54

25# batman


汗,plp兄的话题激起了我的兴趣,光顾着讨论,没顾及楼主的感受,sorry...




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