当有一个包含 this1 的文本文件 test.txt 时:



以下代码返回删除第一个字符的文本文件的内容:

< "test.txt" (
    > nul pause
    findstr "^"
)

使用管道时也会发生同样的情况:
type "test.txt" | (
    > nul pause
    findstr "^"
)

因为 pause 命令只需要一个字符。

但是,当用以下任一命令替换 pause 命令时,输出为空,尽管 - 就像 pause - 它们仅提示 ( /W ) 输入单个字符:
  • 2> nul xcopy /W ? .
  • replace /W /U ? .

  • 这是为什么,这里发生了什么?xcopy /Wreplace /W 是否消耗了所有重定向/管道文本数据,甚至是多行,尽管它们只显示接收到的第一个字符?他们在搞乱文件指针吗?
    有没有办法防止这些命令吸收多个字符?

    1...最后一行以换行符终止,以便 findstr 不会无限期挂起 - 请参阅此线程:What are the undocumented features and limitations of the Windows FINDSTR command?,如果重定向输入不以 <LF> « 结尾,»FINDSTR 部分将卡在 XP 和 Windows 7 上。

    最佳答案

    重定向与管道之间的行为实际上略有不同。
    重定向
    看起来 XCOPY 和 REPLACE 只是将标准输入文件指针移动到文件结尾(EOF)。
    如果您使用 FIND /V "" 而不是 FINDSTR "^" ,那么您将获得整个文件作为输出,因为 FIND 在启动时将文件指针重置为文件的开头。所以标准输入流在 XCOPY 运行后仍然有效,但文件指针在 EOF。
    XCOPY 必须在没有实际读取所有数据的情况下移动文件指针,因为当我使用包含 0.5 GBytes 的 big.txt 时,它仍然是“即时的”。如果 XCOPY 必须在继续之前读取所有文件,则会有明显的延迟。
    管道
    我不完全理解这的含义,但我相信标准管道是块缓冲的。 XCOPY 和 REPLACE 在继续之前最多读取 1 个完整块,留下管道数据的其余部分供 FINDSTR 读取。
    我输入了一个包含 4191 个字节的 127 行文件,FINDSTR 在 3 行中输出了 97 个字节。所以在这种情况下 XCOPY 似乎读取 4094 个字节。
    然后我输入了一个 5000 字节的文件,没有任何新行,FINDSTR 输出 908 字节,这意味着 XCOPY 似乎读取了 4092 字节。
    所以管道块缓冲区必须在 4 KB 附近。我的猜测是 XCOPY 只是将文件指针移动到当前缓冲区的末尾而不读取所有数据,但我不知道如何测试。
    正如预期的那样,在使用管道时,用 FIND 代替 FINDSTR 不会改变结果 - 在已读取管道数据后,无法将文件指针重置回管道数据的开头。

    我无法想象有什么方法可以修改 XCOPY 或 REPLACE 的行为......它就是这样。
    至于为什么 XCOPY 和 REPLACE 的行为方式如此?...我不知道。微软的“批处理”世界是如此独特,以至于我很久以前就放弃了问为什么。

    关于windows - 为什么 XCOPY/W 和 REPLACE/W 会为它们的单字符提示消耗所有重定向的文本数据?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/50242800/

    10-16 12:00