簡體   English   中英

為什么 [IO.File]::WriteAllText 連接 Get-Content -tail ## output,而 Set-Content 沒有?

[英]Why does [IO.File]::WriteAllText concatenate the Get-Content -tail ## output, and Set-Content does not?

如果這是針對此特定問題的重復問題,請原諒我並請指出正確的方向 - 到目前為止,我還沒有在 Stack Overflow 中看到這一點。

我正在使用PowerShell運行一組命令,如下所示在文件中查找“NUL”字符。 -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

我遇到的是[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

使用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

誰能解釋一下有什么區別? 假設“WriteAllText”命令在其為原始格式時有效,但如果以任何方式對其進行處理,它將接受數據作為一個大 blob 是否正確?

[IO.File]::WriteAllText()需要一個(可能是多行)字符串作為其contents參數的參數。

相比之下, Get-Content -Tail 10返回一個字符串數組(當在變量中捕獲時),每個字符串都包含文件中的一行,並且去掉了尾隨的換行符。

PowerShell 執行許多自動類型轉換,雖然它們通常很有幫助,但有時它們不是:在這里,它通過將每個元素與每個[1]連接起來,自動將數組轉換為單行字符串,如下所示示例演示:

PS> "$('line1', 'line2')" # stringify an array
line1 line2  # elements were joined with a space

在您的[IO.File]::WriteAllText()調用的上下文中存儲在$Lines中的數組的這種自動字符串化導致了您的問題。

因此,請改用[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+ ,一致 - 默認為無 BOM 的 UTF-8。


作為旁白:

  • [IO.File]::ReadAllText()的 PowerShell 替代方法是將Get-Content-Raw開關一起使用。

  • 您已經知道Set-Content[IO.File]::WriteAllLines()的 PowerShell 替代品。 如果您將單個多行字符串[IO.File]::WriteAllText()給它並指定
    -NoNewline開關。


[1] 空格字符是默認值,您可以通過$OFS首選項變量覆蓋它,盡管這在實踐中很少見。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM