【问题标题】:PowerShell Set-Content and Out-File - what is the difference?PowerShell Set-Content 和 Out-File - 有什么区别?
【发布时间】:2012-05-18 15:48:32
【问题描述】:

在 PowerShell 中,Out-FileSet-Content 有什么区别?还是Add-ContentOut-File -append

我发现如果我对同一个文件使用两者,文本完全是mojibaked

(第二个小问题:>Out-File 的别名,对吧?)

【问题讨论】:

    标签: powershell


    【解决方案1】:

    这是我在使用 PowerShell 几个月的经验和一些科学实验后得出的结论摘要。我从未在文档中找到任何这些:(

    [更新:其中大部分内容现在似乎得到了更好的记录。]

    读写锁定

    Out-File 正在运行时,另一个应用程序可以读取日志文件。

    Set-Content 正在运行时,其他应用程序无法读取日志文件。因此永远不要使用Set-Content来记录长时间运行的命令。

    编码

    Out-File 默认保存为Unicode (UTF-16LE) 编码(尽管可以指定),而Set-Content 在PowerShell 3+ 中默认为ASCII (US-ASCII)(这也可能被指定)。在早期的 PowerShell 版本中,Set-ContentDefault (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.
    【解决方案2】:

    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 会。
    • @MattHickford 这有点奇怪。该代码通过管道传递给 $null,因此 Add-Content 不会收到任何内容。如果Add-Content 没有收到任何东西,为什么要创建一个文件?另一方面,同样的问题可能会被问到 Out-File。
    • 区别对我很重要gci $folder | Out-File log.txt ; cat log.txt 有效,而gci $folder | Add-Content log.txt ; cat log.txt 爆炸了
    • @MattHickford 我可能会在尝试处理文件之前确保文件存在。可能是所有语言的好习惯。
    • 另一个区别是在使用Set-Content时,该文件对其他应用程序不可用。
    【解决方案3】:

    好吧,我不同意... :)

    1. Out-File 具有-Append(-NoClober 用于避免覆盖),它将添加内容。但这不是同一只野兽。
    2. 命令 | Add-Content 将在输入上使用 .ToString() 方法。 Out-File 将使用默认格式。

    所以:

    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)与 ToString(Add-Content)的好点
    • 我的意思是:尽管两者的作用通常相同,但别名在 PowerShell 中具有它的含义……所以我也不会使用这个术语来描述它们之间的关系……;) 别名替换命令,在这种情况下,它应该使用语法:ls | > file.txt 可能。显然,这行不通……
    • 默认格式是给定对象在控制台中的显示方式。大多数核心 cmdlet/对象类型都有格式化元数据,通知 PowerShell 如何以用户友好的方式显示它们。换句话说:将命令的结果通过管道传输到 Out-File 可用于将命令的输出保存到文件中,而不会丢失 PowerShell 完成的格式化。
    • 是的,我认为> 不完全等同于out-file 是一个重要的区别。如果你设置$PSDefaultParameterValues["Out-File:Encoding"] = "UTF8",它会被>忽略。
    【解决方案4】:

    Set-Content 支持-Encoding Byte,而Out-File 不支持。

    所以当你想将二进制数据或Text.Encoding#GetBytes()的结果写入文件时,你应该使用Set-Content

    【讨论】:

      【解决方案5】:

      想补充一下编码的区别:

      带有 PowerShell 5.1 的 Windows:

      • Out-File - 默认编码为 utf-16le
      • Set-Content - 默认编码是 us-ascii

      带有 PowerShell 7.1 的 Linux:

      • Out-File - 默认编码是 us-ascii
      • Set-Content - 默认编码是 us-ascii

      【讨论】:

        【解决方案6】:

        Out-file -append>> 实际上可以在同一个文件中混合两种编码。即使文件最初是 ASCII 或 ANSI,它也会默认在其底部添加 Unicode。 Add-content 将在追加之前检查编码并匹配它。顺便说一句,export-csv 默认为 ASCII(无重音符号),set-content/add-content 为 ANSI。

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2014-10-29
          • 2015-08-22
          • 2011-07-05
          • 2012-09-02
          • 2021-10-25
          • 2019-07-10
          • 1970-01-01
          • 2013-01-08
          相关资源
          最近更新 更多