当有文本文件时 test.txt
包含这个1:
test data
以下代码返回删除第一个字符的文本文件的内容:
< "test.txt" (
> nul pause
findstr "^"
)
使用管道时也会发生同样的情况:
type "test.txt" | (
> nul pause
findstr "^"
)
因为 pause
命令只需要一个字符。
但是,当替换 pause
时通过以下任一命令执行命令,输出为空,尽管 - 类似于 pause
– 他们仅提示 ( /W
) 单个字符:
-
2> nul xcopy /W ? .
-
replace /W /U ? .
这是为什么,这里发生了什么?
是xcopy /W
和 replace /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运行后stdin流仍然有效,但是文件指针在EOF。
XCOPY 必须在没有实际读取所有数据的情况下移动文件指针,因为当我使用包含 0.5 GBytes 的 big.txt 时,它仍然是“即时的”。如果 XCOPY 在继续之前必须读取所有文件,将会有明显的延迟。
管道
我不完全理解这意味着什么,但我相信标准管道是 block 缓冲的。 XCOPY 和 REPLACE 在继续之前最多读取 1 个完整 block ,将剩余的管道数据留给 FINDSTR 读取。
我输入了一个包含 4191 个字节的 127 行文件,FINDSTR 在 3 行中输出了 97 个字节。所以在这种情况下,XCOPY 似乎读取了 4094 个字节。
然后我在一个没有任何新行的 5000 字节文件中通过管道传输,FINDSTR 输出 908 字节,这意味着 XCOPY 似乎读取 4092 字节。
所以管道 block 缓冲区必须在 4 kbytes 附近的某个地方。我的猜测是 XCOPY 只是将文件指针移动到当前缓冲区的末尾而不读取所有数据,但我不知道如何测试它。
正如预期的那样,在使用管道时用 FIND 代替 FINDSTR 不会改变结果 - 在读取数据后无法将文件指针重置回管道数据的开头。
我无法想象有任何方法可以修改 XCOPY 或 REPLACE 的行为...它就是这样。
至于为什么 XCOPY 和 REPLACE 的行为方式是这样的?......我没有任何线索。 Microsoft 的“批处理”世界是如此奇特,以至于我很久以前就放弃了问为什么。
关于windows - 为什么 XCOPY/W 和 REPLACE/W 为它们的单字符提示消耗所有重定向的文本数据?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50242800/