1

I am trying to understand the output & error message for:

# declare empty array
$thisDataArray = @()
# assign array values
$thisDataArray = '123','cadabra','456','789','trouble'
# declare empty array to receive specific values
$letters = @()
# use this pattern to filter array members that contain letters
$regex = "[a-z]"

# confirm the array values
Write-Host $thisDataArray
# pipe array & filter to find the values
$thisDataArray | Select-String -AllMatches -Pattern $regex -CaseSensitive | ForEach-Object { $letters = $_.Matches.Value} 
# output the result
Write-Host $letters

The error is: The variable $letters is assigned but never used. And the output is:

123 cadabra 456 789 trouble
t r o u b l e

My questions are:

  1. How is Write-Host $letters not using the assigned variable $letters?
  2. Why do I only get the one array member 'trouble' from my $regex?
  3. And finally. Why are there spaces between the chars of trouble e.g 't r o u b l e'

Any suggestions appreciated.

1 Answer 1

2
  1. How is Write-Host $letters not using the assigned variable $letters?

Because it is outside the ForEach-Object loop, hence, you're only reading the last result from that variable assignment. You probably wanted:

$thisDataArray | Select-String -AllMatches -Pattern $regex -CaseSensitive | ForEach-Object {
    $letters = $_.Matches.Value
    Write-Host $letters
}

Though, is worth noting that output to console is implicit unless captured or redirected, so, Write-Host might not be needed nor is a variable assignment:

$thisDataArray | Select-String -AllMatches -Pattern $regex -CaseSensitive | ForEach-Object {
    $_.Matches.Value
}
  1. Why do I only get the one array member 'trouble' from my $regex?

You don't, you would get cadabra and trouble assuming Write-Host is inside the loop.

  1. And finally. Why are there spaces between the chars of trouble e.g t r o u b l e

Because your regex [a-z] matches a single character and since -AllMatches is being used, all appeareances of a character match are being outputted. The reason why they then appear concatenated by a space is because Write-Host is stringifying the $letters array and joining it by $OFS (default $OFS is a space). i.e.:

PS ..\pwsh> $letters      
t
r
o
u
b
l
e

PS ..\pwsh> Write-Host $letters
t r o u b l e

PS ..\pwsh> [string] $letters
t r o u b l e

PS ..\pwsh> $ofs = ''
PS ..\pwsh> [string] $letters
trouble
  • If you want to match all letters from a to z you could use:
$regex = "[a-z]+"
  • If you want to match those elements $thisDataArray which have only letters from a to z then you could use:
$regex = "^[a-z]+$"

As for the "error" The variable $letters is assigned but never used, I assume you're referring to a PSScriptAnalyzer Rule, namely UseDeclaredVarsMoreThanAssignments, which simply means, that the variable being assigned inside a script block (ForEach-Object -Process { ... } in this case) is never used inside that script block:

enter image description here

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.