为什么Set Content中的backtick不创建多行



这两个命令都不会创建多行文本:

Set-Content .test.md 'Hello`r`nWorld'
Set-Content .test.md 'HellornWorld'

只有这样才能

Set-Content .test.md @("Hello`nWorld")

你知道为什么吗?

  • 转义序列(如`r`n)仅在"..."内部工作,即可扩展(插值)字符串。

    • 相比之下,'...'字符串(单引号)逐字的字符串不会解释其内容-甚至`实例也被用作逐字的(字面上)
  • 只有`(即所谓的backtick)用作PowerShell中的转义字符,而不是

    • 也就是说,在"..."'...'字符串中,是一个文字,即逐字使用
    • (但是,是正则表达式(正则表达式)上下文中的转义符,但它是。NET正则表达式引擎来解释它们,而不是PowerShell;例如。,
      "`r" -match 'r'$true:(插值)文字CR字符。匹配其转义的regex表示)

注意:`-转义也适用于未加引号的令牌,但前提是它们充当命令参数;例如Write-Output line1`r`nline2等同于"line1`r`nline2"


至于您尝试了什么

  • 事实上,上一个命令中的"Hello`nWorld"是一个使其工作的"..."字符串。

    • 相比之下,将字符串封装在@(...)(数组子表达式运算符)中是解决方案的附带。(Set-Content的(位置隐含的)-Value参数是数组-无论如何都有值(System.Object[]),因此即使是传递的单个字符串也会被强制到数组)
  • 最后,请注意Set-Content默认情况下会向输出文件中添加一个尾随的平台本机换行符;使用-NoNewLine来抑制这种情况,但请注意,这样做也不会在多个输入对象之间放置换行符(如果适用的话)(在您的情况下,只有一个)。

因此(注意-NoNewLine和后面的`n):

Set-Content -NoNewLine .test.md "Hello`nWorld`n"

可选阅读:PowerShell行为的设计原理:

为什么PowerShell不像其他语言那样使用反斜杠()作为转义符

因为PowerShell必须(也)在Windows上运行(它最初只是Windows),所以使用作为转义符(从Unix(POSIX兼容)shell(如Bash)中已知)是而不是选项,因为在Windows上用作路径分隔符

如果是转义符,则必须使用Get-ChildItem C:\Windows\System32而不是Get-ChildItem C:WindowsSystem32,这在处理文件系统路径非常常见的shell中显然是不切实际的。

因此,必须选择一个不同的字符,结果是`,即所谓的backtick:至少在美国键盘上,它很容易键入(就像一样),而且它的好处是在现实世界的字符串中很少出现(就像它本身一样),因此很少需要转义

请注意,Windows上的旧外壳cmd.exe也必须选择不同的字符:它选择了^,即所谓的插入符号

为什么它不像其他语言那样可互换地使用单引号和双引号

不同的语言做出了不同的设计选择,但在进行"..."字符串插值时,'...'字符串而不是PowerShell遵循了此处的现有语言,即POSIX兼容shell的语言,如Bash。作为对后者的改进,PowerShell还支持在'...'中嵌入逐字逐句的',转义为''(例如'6'' tall')

考虑到PowerShell对向后兼容性的承诺,这种行为不会改变,特别是考虑到它对语言的基础性。

从概念上来说,你可以争辩说,字符串使用的引用字符的方面应该与是否是插值分开,这样你就可以自由地选择一种或另一种引用风格,以方便句法,而单独控制是否应该进行插值。

因此,假设,PowerShell可以使用一个单独的sigil进行字符串插值,比如$"..."$'...'(类似于C#现在提供的内容,尽管它显然只有一个字符串引用样式)。(顺便说一句:Bash和Ksh有这种语法形式,但它有不同的用途(字符串的本地化),很少在实践中使用)。

然而,在实践中,一旦您了解了"..."'...'在PowerShell中的工作方式,就不难使它们按预期工作。


有关PowerShell、cmd.exe和POSIX兼容shell的基本功能,请参阅此答案。

相关内容

  • 没有找到相关文章

最新更新