【发布时间】:2012-05-18 15:48:32
【问题描述】:
在 PowerShell 中,Out-File 和 Set-Content 有什么区别?还是Add-Content 和Out-File -append?
我发现如果我对同一个文件使用两者,文本完全是mojibaked。
(第二个小问题:> 是Out-File 的别名,对吧?)
【问题讨论】:
标签: powershell
在 PowerShell 中,Out-File 和 Set-Content 有什么区别?还是Add-Content 和Out-File -append?
我发现如果我对同一个文件使用两者,文本完全是mojibaked。
(第二个小问题:> 是Out-File 的别名,对吧?)
【问题讨论】:
标签: powershell
这是我在使用 PowerShell 几个月的经验和一些科学实验后得出的结论摘要。我从未在文档中找到任何这些:(
[更新:其中大部分内容现在似乎得到了更好的记录。]
Out-File 正在运行时,另一个应用程序可以读取日志文件。
Set-Content 正在运行时,其他应用程序无法读取日志文件。因此永远不要使用Set-Content来记录长时间运行的命令。
Out-File 默认保存为Unicode (UTF-16LE) 编码(尽管可以指定),而Set-Content 在PowerShell 3+ 中默认为ASCII (US-ASCII)(这也可能被指定)。在早期的 PowerShell 版本中,Set-Content 以 Default (ANSI) 编码写入内容。
编者注:PowerShell 自 5.1 版起仍然默认为特定于文化的 Default(“ANSI”)编码,尽管文档声称.如果 ASCII 是默认值,则非 ASCII 字符(例如 ü)将转换为 literal ?,但 不是 的情况:'ü' | Set-Content tmp.txt; (Get-Content tmp.txt) -eq '?' 产生 @ 987654341@.
PS > $null | out-file outed.txt
PS > $null | set-content set.txt
PS > md5sum *
f3b25701fe362ec84616a93a45ce9998 *outed.txt
d41d8cd98f00b204e9800998ecf8427e *set.txt
这意味着两个命令的默认值是不兼容的,混合它们会破坏文本,所以总是指定一个编码。
正如 Bartek 所解释的,Out-File 保存了输出的精美格式,如终端所示。所以在有两个文件的文件夹中,dir | out-file out.txt 命令会创建一个有 11 行的文件。
而Set-Content 保存了更简单的表示。在包含两个文件的文件夹中,命令dir | set-content sc.txt 创建一个包含两行的文件。模拟终端中的输出:
PS > dir | ForEach-Object {$_.ToString()}
out.txt
sc.txt
我相信这种格式会导致换行,但我还不能描述它。
Set-Content 无法可靠地创建空文件,而 Out-File 会:
在空文件夹中,dir | out-file out.txt 命令会创建一个文件,而dir | set-content sc.txt 不会。
Set-Content 从管道中获取文件名;允许您将多个文件的内容设置为某个固定值。
Out-File 从管道中获取数据;更新单个文件的内容。
Set-Content 包括以下附加参数:
Out-File 包括以下附加参数:
有关这些参数是什么的更多信息,请参阅帮助;例如get-help out-file -parameter append.
【讨论】:
Set-Content 默认编码:转换为(Get-Culture).Textinfo.ANSICodePage (Windows 8.1, Powershell 4.0, CurrentCulture cs-CZ, CurrentUICulture en-GB, ANSICodePage 1250, OEMCodePage @9876543663@, 使用@987测试@string 在上面的代码页中有不同的代码)。
Out-File 在某些情况下存在排长问题。例如:$x = [pscustomobject]@{A=('a' * 500); B=('b' * 500)}; $x | Out-File -Path myfile.txt.
Out-File 具有覆盖输出路径的行为,除非设置了-NoClobber 和/或-Append 标志。 Add-Content 将在默认情况下已经存在输出路径的情况下附加内容(如果可以的话)。如果一个文件尚不存在,两者都将创建该文件。
另一个有趣的区别是Add-Content 默认创建一个 ASCII 编码文件,Out-File 默认创建一个 little endian unicode 编码文件。
> 是Out-File 的别名语法糖。它是Out-File,带有一些预定义的参数设置。
【讨论】:
echo "" > $null | Add-Content abc.txt 它不会创建文件 abc.txt,而 Out-File 会。
Add-Content 不会收到任何内容。如果Add-Content 没有收到任何东西,为什么要创建一个文件?另一方面,同样的问题可能会被问到 Out-File。
gci $folder | Out-File log.txt ; cat log.txt 有效,而gci $folder | Add-Content log.txt ; cat log.txt 爆炸了
Set-Content时,该文件对其他应用程序不可用。
好吧,我不同意... :)
所以:
ls | Add-Content test.txt
和
ls | Out-File test.txt
会给你完全不同的结果。
不,'>' 不是别名,它是重定向运算符(与其他 shell 相同)。并且有非常严重的限制......它会以与显示相同的方式切割线条。 Out-File 具有 -Width 参数,可帮助您避免这种情况。此外,对于重定向运算符,您无法决定使用什么编码。
HTH 巴特克
【讨论】:
>和Out-File是同一个东西。他们调用相同的代码。来自 Bruce Payette 的 PowerShell in Action 第二版(Kindle 位置 4646):In fact, myScript > file.txt is just “syntactic sugar” for myScript | out-file -path file.txt In some cases, you’ll want to use Out-File directly because it gives you more control over the way the output is written.
> 不完全等同于out-file 是一个重要的区别。如果你设置$PSDefaultParameterValues["Out-File:Encoding"] = "UTF8",它会被>忽略。
Set-Content 支持-Encoding Byte,而Out-File 不支持。
所以当你想将二进制数据或Text.Encoding#GetBytes()的结果写入文件时,你应该使用Set-Content。
【讨论】:
想补充一下编码的区别:
带有 PowerShell 5.1 的 Windows:
带有 PowerShell 7.1 的 Linux:
【讨论】:
Out-file -append 或>> 实际上可以在同一个文件中混合两种编码。即使文件最初是 ASCII 或 ANSI,它也会默认在其底部添加 Unicode。 Add-content 将在追加之前检查编码并匹配它。顺便说一句,export-csv 默认为 ASCII(无重音符号),set-content/add-content 为 ANSI。
【讨论】: