[英]Why does [IO.File]::WriteAllText concatenate the Get-Content -tail ## output, and Set-Content does not?
If this is a duplicate question for this specific issue, forgive me and please kindly point me in the right direction - I have not seen this in Stack Overflow so far.如果这是针对此特定问题的重复问题,请原谅我并请指出正确的方向 - 到目前为止,我还没有在 Stack Overflow 中看到这一点。
I'm using PowerShell
to run a set of commands as follows to find 'NUL' char's in a file.我正在使用PowerShell
运行一组命令,如下所示在文件中查找“NUL”字符。 ( -replace
works just fine - this is not my problem) ( -replace
工作得很好 - 这不是我的问题)
$findString = '\x00'
$replString = 'DERPS'
$foo = [IO.File]::ReadAllText("C:\SomeFile.txt")
$bar = $foo -replace $findString, $replString
[IO.File]::WriteAllText("C:\SomeFile_2.txt", $bar)
$Lines = Get-Content "C:\SomeFile_2.txt" -tail 10
#I have also used the following with the same effect:
#$Lines = Get-Content "C:\SomeFile_2.txt" |Select-Object -last 10
[IO.File]::WriteAllText("C:\FOOBARRED.txt", $Lines)
Set-Content "C:\NOT_FOOBARRED.txt" $Lines
What I'm experiencing is with [IO.File]
it concatenates the last 10 lines into one string:我遇到的是[IO.File]
它将最后 10 行连接成一个字符串:
Line 1 of 10 Line 2 of 10 Line 3 of 10 Line 4 of 10 Line 5 of 10 Line 6 of 10 Line 7 of 10 Line 8 of 10 Line 9 of 10 DERPSDERPSDERPSDERPSDERPS
With Set-Content
my output looks correct:使用Set-Content
我的 output 看起来是正确的:
Line 1 of 10
Line 2 of 10
Line 3 of 10
Line 4 of 10
Line 5 of 10
Line 6 of 10
Line 7 of 10
Line 8 of 10
Line 9 of 10
DERPSDERPSDERPSDERPSDERPS
Can anyone explain what the difference is?谁能解释一下有什么区别? Is it correct to assume the "WriteAllText" Command works when it's a raw format, but if it's processed in anyway it will accept the data as one large blob?假设“WriteAllText”命令在其为原始格式时有效,但如果以任何方式对其进行处理,它将接受数据作为一个大 blob 是否正确?
[IO.File]::WriteAllText()
expects a single (potentially multiline) string as the argument to its contents
parameter. [IO.File]::WriteAllText()
需要一个(可能是多行)字符串作为其contents
参数的参数。
By contrast, Get-Content -Tail 10
returns an array of strings (when captured in a variable), each containing a line from the file with the trailing newline stripped.相比之下, Get-Content -Tail 10
返回一个字符串数组(当在变量中捕获时),每个字符串都包含文件中的一行,并且去掉了尾随的换行符。
PowerShell performs many automatic type conversions, and while they're usually helpful, sometimes they're not: here, it automatically converts the array to a single-line string by concatenating the elements with a single space each [1] , as the following example demonstrates: PowerShell 执行许多自动类型转换,虽然它们通常很有帮助,但有时它们不是:在这里,它通过将每个元素与每个[1]连接起来,自动将数组转换为单行字符串,如下所示示例演示:
PS> "$('line1', 'line2')" # stringify an array
line1 line2 # elements were joined with a space
This automatic stringification of the array stored in $Lines
in the context of your [IO.File]::WriteAllText()
call caused your problem.在您的[IO.File]::WriteAllText()
调用的上下文中存储在$Lines
中的数组的这种自动字符串化导致了您的问题。
Therefore, use [IO.File]::WriteAllLines()
instead (note: Lines rather than Text ), which expects an array of strings and writes its elements as lines to the file, terminated with a (platform-native) newline each.因此,请改用[IO.File]::WriteAllLines()
(注意: Lines而不是Text ),它需要一个字符串数组并将其元素作为行写入文件,每个都以(平台原生)换行符终止。
In other words: It acts like Set-Content
when given an array of strings, though note that in Windows PowerShell you'll end up with an ANSI -encoded file by default with Set-Content
, whereas .NET - and now PowerShell (Core) 7+ , consistently - default to BOM-less UTF-8. In other words: It acts like Set-Content
when given an array of strings, though note that in Windows PowerShell you'll end up with an ANSI -encoded file by default with Set-Content
, whereas .NET - and now PowerShell (Core) 7+ ,一致 - 默认为无 BOM 的 UTF-8。
As an aside:作为旁白:
A PowerShell alternative to [IO.File]::ReadAllText()
is to use Get-Content
with the -Raw
switch. [IO.File]::ReadAllText()
的 PowerShell 替代方法是将Get-Content
与-Raw
开关一起使用。
You're already aware of Set-Content
as the PowerShell alternative to [IO.File]::WriteAllLines()
.您已经知道Set-Content
是[IO.File]::WriteAllLines()
的 PowerShell 替代品。 It can also act as an alternative to [IO.File]::WriteAllText()
if you pass it a single, multiline string and also specify the如果您将单个多行字符串[IO.File]::WriteAllText()
给它并指定-NoNewline
switch. -NoNewline
开关。
[1] A space character is the default , which you can override via the $OFS
preference variable , though that is rarely seen in practice. [1] 空格字符是默认值,您可以通过$OFS
首选项变量覆盖它,尽管这在实践中很少见。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.