Powershell 中的换行符 `r`n 和 `n 有什么区别?

What is the difference between `r`n and `n for line breaks in Powershell?

我知道windows和unix有不同的换行代码。但在 Powershell 中,`r`n`n 都适用于换行符。 是否有从 `n`r`n 的自动转换,为什么必须使用引号而不是反斜杠?

如果您正在谈论脚本,PowerShell 将在解析时平等地解释 \n\r\n 行尾 (EOL) 序列。 \r\n EOL 主要是 Windows 过去的产物,大多数现代(约 2018 年)Windows 发布的应用程序将对它们进行相同的解释。

这些不是引号,而是 重音符反引号(大多数键盘上的波浪键),它们是指定的字符串转义符PowerShell 中的字符。

影响 Windows PowerShell 脚本解析的一件事是字节顺序标记 (BOM) 的使用。这是让 PowerShell 解释器在您的代码中看到 unicode(例如表情符号)的唯一方法;即,通过使用 UTF8-BOM。

当使用 get-content(没有 -raw)将文件读入字符串数组时,根本没有行结束符。然后 out-file (">") 或 set-content 将根据操作系统放入行结尾。 Mac OS 以前只是 `r,但现在就像 unix,`n.

这是 osx 中的一个文件,其中只有 `n (0x0A):

format-hex file


   Label: /Users/js/foo/file

          Offset Bytes                                           Ascii
                 00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F
          ------ ----------------------------------------------- -----
0000000000000000 61 62 63 0A 61 62 63 0A                         abc�abc�

我有一个关于转换格式的post:Unix newlines to windows newlines (on Windows)

  • 输入 上,PowerShell 接受 `r`n(Windows 样式)和 `n (Unix 风格)和 newlines interchangeably, irrespective of the platform (OS) it runs on; this applies both to reading PowerShell source-code files (such as *.ps1 scripts) and to all built-in cmdlets that read text, notably Get-Content.

    • `n 是 LF,LINE FEED,U+000A 字符, 本身 用作 [=133= 上的换行符]类Unix平台.

    • `r`n是CRLF,换行符sequence紧跟一个CARRIAGERETURN(U+000D)字符组成由 LF,用作 Windows.

      上的换行符
    • 上面用了
    • `,因为`反引号 (正式名称为 GRAVE ACCENT,PowerShell 中的 U+0060) that serves as the escape character,与许多其他语言不同,它是 \(例如,PowerShell 中的 `n 对应于 [= C# 中的 23=] 和 JavaScript,以及 `r`n\r\n

      • ` 在 PowerShell 中用作转义字符:

        • expandable strings里面("...";但是'...'里面没有,其内容被使用逐字) 没有
        • in unquoted 传递给命令的参数,其主要目的是转义 元字符; 等字符具有语法功能),即使用它们 verbatim;例如,Write-Host a`;b)
        • 请参阅概念性 about_Special_Characters 帮助主题以获取更多信息和 支持的转义序列列表
      • 请注意,在 regex 上下文中(例如通过 -match-replace 运算符),\-基于转义序列(例如 \n)仍然可以发挥作用,即当这些转义序列由 .NET 正则表达式引擎 而不是 PowerShell 本身(例如"a`nb" -replace '\n' 产量 'ab');请参阅概念性 about_Regular_Expressions 帮助主题。

  • On output,PowerShell 使用 platform-native 换行序列:`r`n 在 Windows 上,`n 在类 Unix 平台上。

    • 这适用于 文本文件创建 cmdlets 的使用,其中包括:

      • 用于 纯文本 文件创建的 Cmdlet:Set-ContentOut-File / 重定向运算符 >.
      • 创建 结构化文本 文件的 Cmdlet,例如 Export-Csv.
    • 顺便说一句:

      • PowerShell [Core] 6+中,创建文本文件时一贯使用的字符编码(和阅读) 是 UTF-8 without a BOM.

      • 相比之下,在 Windows PowerShell(PowerShell 版本高达 5.1)中,默认编码因 cmdlet 而异,并选择 UTF-8通过输出 cmdlet 的 -Encoding 参数总是创建一个文件 一个 BOM。

      • 有关 Windows PowerShell 与 PowerShell [Core] 中(默认)字符编码的更多信息,请参阅


至于你的具体问题

Is there an automatic conversion from `n to `r`n?

从某种意义上说,是的:

使用创建文本文件的 cmdlet 保存到文件隐式使用 平台原生 换行序列,如上所述。

因此,使用 Get-Content 读取文件(默认情况下逐行 读取文件 )并将这些行保存回文件 Set-Content 将有效地导致原始换行符转换为平台本地换行符,如果原始换行符来自各自的其他世界。

请注意,另外,字符编码可能会改变,因为一旦字符串被读入到内存,有关输入文件字符的信息编码丢失,创建文本文件的 cmdlet(例如 Set-Content)在输出上应用它们的 默认 编码 - 有关背景信息,请参阅

有针对性地转换为 特定的 换行样式,无论您 运行 在什么平台上 ,都需要更多工作。

  • 参见 this answer

why do you have to use backticks (`) instead of backslashes (\)?

\ 因为转义字符对于 PowerShell 来说不是一个好的选择,因为 \ 用于 文件路径 ,假定 \ 作为 Windows 上的(主要) 文件系统路径分隔符 ,并且假定将文件路径作为参数传递是shell 中非常常见的用例。

必须 \-转义这些路径分隔符以消除它们与 \ 作为转义字符的歧义(例如,"C:\Program Files\PowerShell" 而不是 "C:\Program Files\PowerShell")本来是不必要的负担(这种转义在 C# 和 JavaScript 等编程语言中已经够烦人的了,尽管最近的版本现在提供了不需要转义的替代语法形式)。

因此,PowerShell 需要一个不同的转义字符,并选择了 `,因为:

  • 文字中很少见;也就是说,您很少需要转义 ` 本身 - 作为 `` - 为了使用它 verbatim.

  • 至少在英文键盘上打字很容易

其他炮弹:

  • cmd.exe 也不得不选择不同的转义字符,并选择了 ^脱字符(正式名称为 CIRCUMFLEX ACCENT , U+005E).

  • POSIX-like shells 如 Bash 从未遇到过这个问题,因为它是 /,而不是 \ Unix 文件系统路径中的分隔符;因此,这些 shell 使用 \ 作为转义字符,就像大多数编程语言一样。