Ian
Ian

Reputation: 1

Get-Content issue with -eq as string

As part of a bigger script I need to verify a file contents before continuing. However, it's not working when I use | Out-String.

Note this needs to work under powershell v2 unfortunately. The file I am looking at contains the data:

{"somedata":5,"hello":[]}

If I remove | Out-String from the command then it tells me the file matches.

But if I add data to the file, then it still tells me the file matches when it doesn't. If I add | Out-String then it tells me the file doesn't match when it does...

$filecheck = Get-Content ("C:\temp\hello.txt") | Out-String
Write-Host $filecheck
if ($filecheck -eq '{"somedata":5,"hello":[]}') {
    Write-Host "file matches"
} else {
    Write-Host "doesn't match"
}

Upvotes: 0

Views: 320

Answers (2)

tukan
tukan

Reputation: 17337

Edit - the script will exit on first match.
Edit2 - you don't need the Else branch if nothing is found print 'failed' at the end suffice.

What about piping into Foreach-Object like this:

 (Get-Content 'C:\<our_path>\test.txt') |
        Foreach-Object { If ($_ -eq '{"somedata":5,"hello":[]}') {write-host 'matches'; exit}} 
 write-host 'failed'

I have kept your format of -eq, even thou, I would recommend regex for string/text search.

Upvotes: 1

vonPryz
vonPryz

Reputation: 24071

As how to fix the issue, see @tukan's answer. Anyway, for learning purposes, let's explore the root cause, namely using the Out-String cmdlet. It actually adds a newline to the string. Like so,

PS C:\temp> $filecheck = Get-Content ("C:\temp\hello.txt") | Out-String
PS C:\temp> write-host $filecheck
{"somedata":5,"hello":[]}

PS C:\temp>

As the data contains a newline, it isn't equal to the string literal used in the if statement. Thus the comparison fails. Remove the Out-String and it works:

PS C:\temp>$filecheck = Get-Content ("C:\temp\hello.txt")
PS C:\temp> $filecheck
{"somedata":5,"hello":[]}
PS C:\temp> $filecheck -eq '{"somedata":5,"hello":[]}'
True
PS C:\temp>

Earlier you noted that Out-String was needed as otherwise adding data would still make the comparison to fail. Why is that? Let's say the data in file is

{"somedata":5,"hello":[]}
{"moredata":1,"foo":bar}

What now happens is that Get-Content will give you an array of strings. The 2nd line consists of {"moredata":1,"foo":bar} plus a newline. Passing such a construct to the comparison will evaluate just the first element, thus a match.

When you pass an array to Out-String, the result is actually a string with data, newline, data and extra newline:

PS C:\temp> $filecheck|out-string
{"somedata":5,"hello":[]}
{"moredata":1,"foo":bar}

PS C:\temp>

This obviously isn't equal to the string literal used in the if statement.

Upvotes: 6

Related Questions