【问题标题】:Powershell: split string with newline, then use -containsPowershell:用换行符分割字符串,然后使用 -contains
【发布时间】:2017-07-02 02:53:08
【问题描述】:
$a = {aa
bb
cc}
$a = $a -split "`n"
$a -contains "aa"

当字符串“aa”似乎是列表的一部分时,这将返回 false。为什么是这样?

【问题讨论】:

  • 尽管您的问题看起来很明显,但它会帮助您对其进行编辑以便进一步阐述;你想达到什么目标,等等。
  • 你到底为什么要拆分一个脚本块? (提示:您是交互式 shell 中的程序员。PowerShell 在返回 false 时没有说谎,这意味着 aa 不是列表的一部分,这意味着您应该查看列表包含的内容。($a -split "`n")[0].Length => 3 例如)
  • -Contains 是一个列表运算符(列表是否包含项目)。您希望 -like、-match 或 .Contains()(一种字符串方法)执行您要查找的操作。
  • @MikeShepard:OP 使用转换为 多行字符串脚本块 是不寻常的,但代码确实可以作为-is 如果脚本块是在常规控制台中定义的(它使用 LF-only 行结尾) - 粘贴它并执行它以查看。相比之下,如果代码是在使用 CRLF 行尾的脚本中定义的,则它将不起作用。
  • @mklement0 - 我应该学会更仔细地阅读人们的代码。我看到 string 和 -contains 并得出结论(通常是正确的)他们使用了错误的运算符。

标签: powershell


【解决方案1】:

补充Kory Gill's helpful answer,这表明问题可能是输入有CRLF("`r`n")行结尾,在这种情况下-split "`n"(仅由LF分割)将离开结果数组元素带有尾随 CR ("`r"),导致 "aa" 无法与 -contains 一起找到,因为实际值为 "aa`r"

通用使用 Windows-Unix风格的行尾处理输入的方法是使用:

$a -split '\r?\n' # split $a into lines, whether it has CRLF or LF-only line endings

-split operator 使用regexes (regular expressions),正则表达式\r?\n 匹配任何LF (\n),可能(?) 前面有一个CR (\r)。要匹配(罕见的)仅限 CR 的换行符,请使用 \r?\n|\r
Regex 转义序列 \r\n 对应于 PowerShell 转义序列 `r`n(仅适用于双引号字符串)。

请注意,PowerShell 本身在行尾方面非常灵活:

  • 即使在 Windows 上 interactive 常规控制台中的输入也使用 LF-only 行尾 (\n)obsolescent ISE 除外)。

  • 脚本可以有 CRLF (\r\n) 或 LF (\n) 行结尾,并且PowerShell 保留源文件的行结尾在任何定义的多行字符串文字中在文件中。

    • 请注意,这甚至适用于多行 脚本块,如以下问题所示:当您稍后将此类脚本块转换为 字符串 时 - 它只会返回所有内容在脚本块分隔符 {} 之间 - 源文件的行尾会反映在结果字符串中。

顺便说一句:[Environment]::NewLine 包含适合平台的换行符(行尾)序列:Windows 上为"`r`n",类Unix 上为"`n"平台,但是,如上所述,不能保证遇到的所有输入都会有适合平台的换行符

【讨论】:

    【解决方案2】:

    跨平台解决方案:

    $a = $a -split [System.Environment]::NewLine
    

    【讨论】:

    • 虽然了解[Environment]::NewLine 会有所帮助,但将其与-split 一起使用并不是真正的跨平台解决方案,因为您需要准备好处理任何一种 类型的行尾,因为不能保证您只会遇到平台原生的。例如,如果您在常规 PowerShell 控制台在 Windows 中定义多行字符串,它将有 LF-only 行结尾,-split [Environment]::NewLine 将找不到任何行并将整个输入字符串作为一个元素数组返回。
    【解决方案3】:

    每次我在代码中看到一个 `n,我总是质疑它是否应该在 Windows 上是 `r`n。

    把你的代码改成这样:

    $a = $a -split "`r`n"
    

    【讨论】:

    • 或在 any 空白字符处拆分:$a -split "[\s]+"
    • @ST8Z6FR57ABE6A8RE9UF: '\s+' 可以,但请注意,OP 的目的是拆分为 ,而不是通过任何空格运行。
    猜你喜欢
    • 2022-07-06
    • 1970-01-01
    • 2013-11-15
    • 1970-01-01
    • 2012-07-07
    • 2013-02-15
    • 2014-09-23
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多