确实,Get-Content 默认情况下逐行读取并发出输入文件的内容,并带有任何风格的换行符 - CRLF、LF、CR - 已剥离。
虽然该行为可能不熟悉,但对于处理管道中的文件通常有帮助。
正如your answer 所示,-Raw 可用于读取文件完整,而不是作为单行多行字符串 - 这可以提供巨大的性能优势。
举例说明逐行阅读可以提供的便利,结合基于正则表达式的-replace operator对输入 array 的 每个元素 进行操作的能力(如果您的文件具有 LF (\n) 结尾并且您正在选择性地寻找流氓 CRLF (@987654335 @) 以, 开头的行尾,但这无济于事):
# Convenient, but can be made faster with -ReadCount 0 - see below.
@(Get-Content file.txt) -replace ',$' | Set-Content file2.txt
注意:@(...),array-subexpression operator,用于确保Get-Content 调用也输出一个数组,即使文件恰好只有一个 行。
正则表达式锚$ 匹配每个输入字符串(行)的结尾,实际上从每行中删除尾随,,如果存在。 p>
Get-Content 性能说明:
如上所示,-Raw 是迄今为止读取文本文件完整最快的方式 - 但设计上 作为单个多行字符串。
默认行为,逐行读取很慢,尤其是因为PowerShell用元数据装饰每个输出行[1](在-Raw 的情况下,假设只有一个输出字符串,这只会发生一次)。
但是,您可以通过批量读取行来加快速度 - 给定大小的行数组 - 使用 -ReadCount 参数,在这种情况下,只有每个阵列,而不是个别的线条,被装饰。 -ReadCount 0 将所有行读入单个数组。
注意:
-
-ReadCount 改变了流水线在管道中的行为:然后每个数组作为一个整体通过管道发送,这需要计划接收命令,通常通过对接收到的数组执行其自己的枚举,例如使用foreach loop。
-
相比之下,在表达式的上下文中使用-ReadCount 0会导致没有的行为差异,这意味着它可以被使用作为一种简单的性能优化,不需要表达式的其他部分来适应它;以带有-replace 操作的表达式为例:
# Read all lines directly into an array, with -ReadCount 0,
# instead of more slowly letting PowerShell stream the lines
# (emit them one by one) and then collect them in an array for you.
# The -replace operator then acts on each element of the array.
(Get-Content -ReadCount 0 file.txt) -replace ',$'
注意:@(...) 在这种情况下不是必要的,因为-ReadCount 0 总是 发出一个数组,即使对于单行文件也是如此。支持>
性能更好的逐行处理替代方案 - 虽然它不能直接用作 表达式 的一部分 - 是使用 @ 987654327@ 与 -File 参数 - 详情请参阅 this answer。
[1] 此元数据以ETS (Extended Type System) 属性的形式提供,主要提供有关行号和原始文件路径的信息。通过管道将Get-Content 调用| Format-List -Force 以查看这些属性。虽然这些额外信息可能会有所帮助,但附加它对性能的影响是显而易见的。鉴于这些信息通常不需要,至少有一个选择退出会有所帮助:请参阅GitHub issue #7537。