1

PowerShell changes the contents of a text file on Get-Content or the variable on Set-Content.

This is a PowerShell script for compiling a bunch of files and formatting them to a single text file, this part checks if the new file is equal to the old one, but according to the comparison, it never is. I've tried messing with stuff like making the new var be a string array as get-content is.

$files = Get-ChildItem -path "./dir" | Where-Object -FilterScript {$_.Name -match '[A-J]'}

$var = @()
foreach ($file in $files){
    $filePath = "dir\" + $file;
    $fileContent = Get-Content $filepath
    $var += $fileContent
}
$firstLine = '"this" "issen" "da" "first"'
$var1 = '"abc" "def" "12" "6"'
$var2 = '"456" "def" "12" "4"'
$newContent = $firstLine,$var,$var1,$var2
$oldContent = Get-Content './File.txt'

if (-not (Compare-Object $oldContent $newContent)) {
    Write-Host Nothing new.
} else {
    Write-Host Something new
    Set-Content './File.txt' -value $newContent
}
Set-Content './File.txt' -value $newContent
pause

When comparing $newContent to $oldContent which is just $newContent stored and retrieved from a text file they are not identical. They should be, right?

The text files that are gathered from ./dir are like this: a00.txt

a12 bc23 abc

b00.txt

a12 bc23 abg
Jokru
  • 69
  • 12
  • You shouldn't use `-eq` to compare array. Try using `Compare-object`. For more information about comparing array take a look at https://stackoverflow.com/questions/9598173/comparing-array-variables-in-powershell – guiwhatsthat Apr 29 '19 at 11:07

1 Answers1

4

Your first line $var = "stuff","and","thangs" creates an array (3 strings):

enter image description here

The -eq operator doesn't work like that for comparing object arrays. You can instead use the Compare-Object cmdlet:

if (-not (Compare-Object $var $var2)) {
 Write-Host True
} 

Answer to your edit:

Your first variable ($newContent) is an array of strings but also includes another array of strings. See here:

PS D:\temp> $newContent -join ''
"this" "issen" "da" "first"System.Object[]"abc" "def" "12" "6""456" "def" "12" "4"

PS D:\temp> $oldContent -join ''
"this" "issen" "da" "first"a12 bc23 abca12 bc23 abg"abc" "def" "12" "6""456" "def" "12" "4"

A workaround is to pipe the variable to the Out-String cmdlet, but you might find a cleaner way to solve it ;-)

Compare-Object ($oldContent | out-string) ($newContent | out-string)
Martin Brandl
  • 56,134
  • 13
  • 133
  • 172
  • 1
    To elaborate a little more, the reason for this behavior is that the `-eq` operator compares the *identity* of the two array objects and will only return "true" if both variables contain a reference to the exact same object, whereas references to different objects will return "false" even if both objects contain the same elements. – Ansgar Wiechers Apr 29 '19 at 11:07
  • Thanks Ansgar, that explains why it doesn't return true. – Martin Brandl Apr 29 '19 at 11:10
  • This works for the example, but not my actual script and data set – Jokru Apr 29 '19 at 11:14
  • I've no clue why. The actual data set is on multiple lines, can that affect it? I get it with a ```foreach ($file in $files){ $var += $fileContent } ``` – Jokru Apr 29 '19 at 11:16
  • @Jokru Yes, that is a difference because using $var += you *concat* a string whereas the Get-Content cmdlet returns a string array (if you don't use the `-raw` switch) – Martin Brandl Apr 29 '19 at 11:17
  • @MartinBrandl even if I initiated the string as ```$var = @()``` ? – Jokru Apr 29 '19 at 11:25
  • @Jokru Probably yes. Please consider creating a reproducible example, mentioned by Ansgar – Martin Brandl Apr 29 '19 at 11:26
  • @Jokru Sorry, but you didn't provide a verifiable example. There are also variables like $firstline, $var1 and $var2 which are not declared. – Martin Brandl Apr 29 '19 at 11:41
  • Please provide a script which we can copy paste & run that shows the actual issue you have – Martin Brandl Apr 29 '19 at 12:18
  • @MartinBrandl you'll have to copy and paste the files as well – Jokru Apr 29 '19 at 12:25
  • Thank you, my next idea was to just write to a temp file, which would've been messier. – Jokru Apr 29 '19 at 13:03