Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Powershell: split string with newline, then use -contains

Tags:

powershell

$a = {aa
bb
cc}
$a = $a -split "`n"
$a -contains "aa"

This returns false, when the string "aa" is seemingly part of the list. Why is this?

like image 671
Robert Overmyer Avatar asked Feb 13 '17 23:02

Robert Overmyer


2 Answers

To complement Kory Gill's helpful answer, which suggests that the problem may be that the input has CRLF ("`r`n") line endings, in which case -split "`n" (splitting by LF only) would leave the resulting array elements with a trailing CR ("`r"), causing "aa" not to be found with -contains, because the actual value is "aa`r".

The generic way to handle input with Windows- or Unix-style line endings is to use:

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

The -split operator uses regexes (regular expressions), and regex \r?\n matches any LF (\n) possibly (?) preceded by a CR (\r). To also match (rare) CR-only newlines, use \r?\n|\r
Regex escape sequences \r and \n correspond to PowerShell escape sequences `r and `n (which work in double-quoted strings only).

Note that PowerShell itself is quite flexible when it comes to line endings:

  • Even on Windows interactive input in the regular console uses LF-only line endings (\n) (except in the obsolescent ISE).

  • Scripts are allowed to have CRLF (\r\n) or LF (\n) line endings, and PowerShell preserves the source file's line endings in any multi-line string literals defined in the file.

    • Note that this applies even to multi-line script blocks, as in the question: when you convert such a script block to a string later - which simply returns everything between the script-block delimiters, { and } - the source file's line endings are reflected in the resulting string.

As an aside: [Environment]::NewLine contains the platform-appropriate newline (line-ending) sequence: "`r`n" on Windows, "`n" on Unix-like platforms, but, as discussed above, there's no guarantee that all input encountered will have platform-appropriate newlines.

like image 65
mklement0 Avatar answered Oct 21 '22 03:10

mklement0


a solution cross Platform:

$a = $a -split [System.Environment]::NewLine
like image 41
Esperento57 Avatar answered Oct 21 '22 02:10

Esperento57