DraganMilovac93
DraganMilovac93

Reputation: 61

How to parse string in powershell

I have a Powershell command that outputs multiple lines.

I want to output only one line that contains the name of a .zip file.

Currently, all lines are returned when substring .zip is found:

$p.Start() | Out-Null
$p.WaitForExit()
$output = $p.StandardOutput.ReadToEnd()
$output += $p.StandardError.ReadToEnd()
foreach($line in $output)
{  
  if($line.Contains(".zip"))
  {
     $line
  }
}

Upvotes: 2

Views: 3285

Answers (1)

mklement0
mklement0

Reputation: 440297

Since you're using .ReadToEnd(), $output receives a single, multi-line string, not an array of lines.

You must therefore split that string into individual lines yourself, using the -split operator.
You can then apply a string-comparison operator such as -match or -like directly to the array of lines to extract matching lines:

# Sample multi-line string.
$output = @'
line 1
foo.zip
another line
'@

$output -split '\r?\n' -match '\.zip'  # -> 'foo.zip'
  • -split is regex-based, and regex \r?\n matches newlines (line breaks) of either variety (CRLF, as typical on Windows, as well as LF, as typical on Unix-like platforms).

  • -match is also regex-based, which is why the . in \.zip is \-escaped, given that . is a regex metacharacter (it matches any character other than LF by default).

    • Note that -match, like PowerShell in general, is case-insensitive by default, so both foo.zip and foo.ZIP would match, for instance;
      if you do want case-sensitivity, use -cmatch.

As an aside:

I wonder why you're running your command via a [System.Diagnostics.Process] instance, given that you seem to be invoking synchronously while capturing its standard streams.

PowerShell allows you to do that much more simply by direct invocation, optionally with redirection:

$output = ... 2>&1  

Upvotes: 2

Related Questions