在 Powershell 中,`r`n 和 `n 用于换行的区别是什么?

4

我知道在Windows和Unix系统中有不同的换行符代码。但是在PowerShell中,`r`n`n都可用于换行。 是否存在从`n自动转换为`r`n的功能,以及为什么必须使用引号而不是反斜杠?


1
https://devblogs.microsoft.com/scripting/powertip-new-lines-with-powershell/ 以及回车符的解释: https://dev59.com/t3A75IYBdhLWcg3w0cjx微软博客:PowerShell 中的新行 Stack Overflow:回车符、换行符和换页符是什么 - Alex_P
你可以在stackoverflow中使用反斜杠转义反引号。 - js2010
@mklement0 它也适用于帖子,在有两个反引号的情况下。 - js2010
关于您评论的原始形式:` 在帖子中用于未经样式设置的 ` 字符,但如果您想将其用作内联代码片段的一部分,则无法使用该字符。 是Siminho尝试做的事情。 是的,使用_两个_封闭反引号是后者的解决方案,如已更新的问题所示,并且如先前提到的那样。 - mklement0
3个回答

6
  • 在输入时,PowerShell接受`r`n(Windows风格)和`n(Unix风格)以及换行符可互换使用,无论运行平台(操作系统)如何;这适用于读取PowerShell源代码文件(例如*.ps1脚本)和所有读取文本的内置cmdlet,特别是Get-Content

    • `n是LF,即LINE FEED,U+000A字符,在类Unix平台上作为单独的换行符使用。

    • `r`n是CRLF,由CARRIAGE RETURN(U+000D)字符紧随其后的LF组成的换行序列,在Windows上作为换行符使用。

    • 以上使用`,因为它是`,即反引号(正式称为GRAVE ACCENT,U+0060),在PowerShell中充当转义字符,而不像许多其他语言中那样是\(例如,PowerShell中的`n对应于C#和JavaScript中的\n`r`n对应于\r\n)。

      • `在PowerShell中充当转义字符:

        • 可扩展字符串"...";但不在'...'中,其内容会逐字使用)中不是
        • 在传递给命令的未引用参数中使用,其主要目的是转义元字符(具有语法功能的字符,如;),即逐字使用它们;例如:Write-Host a`;b
        • 有关更多信息和支持的转义序列列表,请参阅有关特殊字符的概念帮助主题
      • 请注意,在正则表达式上下文中(例如通过-match-replace运算符),\为基础的转义序列(例如\n)仍然可能起作用,即当这些转义序列由.NET正则表达式引擎而不是PowerShell本身解释时(例如,"a`nb" -replace '\n'产生'ab');请参阅有关正则表达式的概念帮助主题

  • 在输出时,PowerShell使用平台本机换行符序列:Windows上为`r`n,类Unix平台上为`n

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

      • 用于创建纯文本文件的Cmdlet:Set-ContentOut-File / 重定向运算符&

        关于您的具体问题:

        `n自动转换为`r`n吗?

        从某种意义上说,是的:

        使用创建文本文件的命令时,将文件保存到文件中会隐式地使用平台本地的换行序列,如上所述。

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

        请注意,另外,字符编码可能会更改,因为一旦字符串被读入内存,输入文件的字符编码信息就会丢失,而像Set-Content这样的文本文件创建命令会在输出时应用它们的默认编码 - 有关背景信息,请参见this answer

        针对特定的换行样式进行转换,而不考虑您正在运行的平台,需要更多的工作。

        为什么要使用反引号(`而不是反斜杠(\)?

        在PowerShell中,使用\作为转义字符是不明智的选择,因为\用于文件路径,考虑到\在Windows上作为(主要的)文件系统路径分隔符,传递文件路径作为参数是shell中非常常见的用例。

        必须对这些路径分隔符进行\转义,以将其与作为转义字符的\区分开来(例如,使用"C:\\Program Files\\PowerShell"而不是"C:\Program Files\PowerShell")会增加很大负担(尽管在编程语言(如C#和JavaScript)中这种转义已经够烦人了,但最近的版本现在提供了替代语法形式,不需要转义)。

        因此,PowerShell 需要一个不同的转义字符,并选择了 `,原因如下:
        • 在字面使用时 很少出现;也就是说,你很少需要像编程语言中那样将 ` 作为转义字符 - 如 ``

        • 至少在英语键盘上,它很容易输入。

        其他 shell:

        • cmd.exe 也必须选择不同的转义字符,并选择了 ^,即插入符号(CIRCUMFLEX ACCENT,U+005E)。

        • 类似于 Bash 的 POSIX shell 从未遇到这个问题,因为在 Unix 文件系统路径中,分隔符是 / 而不是 \,因此这些 shell 使用 \ 作为转义字符,与大多数编程语言相同。


2
非常好的回答,提供了大量有用的信息 ⭐ - Prid
2
很高兴听到它对你有用,@Prid,我非常感谢你的好评。 - mklement0

1
如果您在讨论脚本,PowerShell 在解析时会将 \n\r\n 的行尾序列等同地解释。而 \r\n 行尾序列大多是过去 Windows 的产物,现代(约 2018 年)的大多数 Windows 应用程序都会将它们解释为相同的内容。
那些不是引号,而是“重音符号”或“反引号”(大多数键盘上的波浪线键),它们是 PowerShell 中指定的字符串转义字符。
影响解析 Windows PowerShell 脚本的一个因素是使用字节顺序标记(BOM)。这是让 PowerShell 解释器在您的代码中查看 Unicode(如表情符号)的唯一方法,即使用 UTF8-BOM。

1
请注意,不仅是 PowerShell 源代码文件(例如脚本)可以接受任何换行符序列(甚至在单个文件中混合使用):所有内置的文本文件读取 cmdlet 都可以,特别是 Get-Content。 虽然越来越普遍的是应用程序可以使用任何序列读取文件,但它们通常会使用平台本地的序列进行写入(尤其是 PowerShell 和 .NET API 在 Windows 上使用 CRLF 序列),这种情况不会很快消失,甚至永远不会消失。 因此,这不是过去的产物。 - mklement0
更具体地说,关于正确解码UTF-8的BOM要求:只有Windows PowerShell(仅限版本5.1及以下的Windows版)需要BOM,而PowerShell [Core](从6开始的跨平台版)始终默认为(无BOM的)UTF-8。 - mklement0
我确实指定了关于Windows PowerShell的部分,但是@mklement0在换行符解析方面做得很好。 - Maximilian Burszley
谢谢。是的,我只是想更明确地提到Windows PowerShell / PowerShell [Core]版本的区别,特别是因为随着时间的推移,PowerShell [Core]将变得越来越重要。总之,要编写跨版本脚本/模块,请将源代码文件保存为UTF-8 _with BOM_。 - mklement0

0

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

我在这里有一篇关于格式转换的帖子: 将Unix换行符转换为Windows换行符(在Windows上)


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接