6

I have a file like this:

line one email1
line two email1
line three email2
line four email1

If I want to extract only the lines that contain "email1", I do this:

$text = Get-Content -Path $path | Where-Object { $_ -like *email1* }

$text is now an array with 3 elements containing those lines, and I iterate through it like this:

for ($i = 0; $i -lt $text.Length; $i++)
{
#do stuff here
}

However, if I want to get the lines containing "email2".

$text = Get-Content -Path $path | Where-Object { $_ -like *email2* }

returns a string, rather than an array of one element. And when I iterate through it, it iterates through each char in the string.

How can I make it an array with one element rather than a string?

4 Answers 4

11

In order to get an array always, even with 1 (i.e. not string) or 0 (i.e. not $null) items, use the operator @():

$text = @(Get-Content -Path $path | Where-Object { $_ -like *email1* })
Sign up to request clarification or add additional context in comments.

Comments

5

Worked it out.

I need to declare $text as type [String[]].

[String[]]$logText = Get-Content -Path $path | Where-Object { $_ -like *email1* }

1 Comment

Good one. See also "more generic" approach in my answer.
3

Instead of getting the Length method to treat a single element statement as an array, I think a better solution would be to use a foreach loop instead of a for loop to iterate:

foreach ($element in $text) {
    #stuff happens
}

will always parse through each element in $text, even if it's a single element.

2 Comments

my problem is that $text is sometimes a string, sometimes an array of String. Foreach on a string would just iterate through each char wouldn't it?
No - if you foreach a string the loop will only run once, since a string only contains a single element (the string itself). Character count has nothing to do with it.
2

You also could use the Select-String Cmdlet, it worked for me even with only one result in the selection :

$text1 = Get-Content -Path $path | Select-String "email1"
$text1 | % { 
    # Do some stuff here
}

$text2 = Get-Content -Path $path | Select-String "email2"
$text2 | % { 
    # Do some stuff here
}

2 Comments

That's because % is an alias for foreach so you're really just relying on what @Kohlbrr said: foreach or % will work on a single string or an array.
@gruntzy thanks - found where using select string with a regex would return the object array I needed!

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.