1

I have been doing a check like this to check last modified date:

if($file1.LastWriteTime -gt $file2.LastWriteTime) { }

How can I do something similar but compare if the files are equal. Note that these files are always just text files.

Samantha J T Star
  • 30,952
  • 84
  • 245
  • 427

3 Answers3

2

You can compare file texts as strings. To do that, first get each file as a single string, then compare them for equality.

$filetext1=[System.IO.File]::ReadAllText("file1.txt")
$filetext2=[System.IO.File]::ReadAllText("file2.txt")
$equal = $filetext1 -ceq $filetext2 # case sensitive comparison
Vesper
  • 18,599
  • 6
  • 39
  • 61
  • Depending on the file size, you might want to avoid variable assignment and maybe do block-by-block comparison instead of the entire file – Mathias R. Jessen Jul 24 '15 at 08:21
  • Indeed, but given that OP says the files are plain text, their size is not expected to be too big. (Although say IIS logs can grow to insane sizes, comparing these for equality is plain useless.) I don't yet know how to read a block from a file via Powershell. (Maybe I should ask or google that) Google said use `[System.IO.Stream]::Read`, I'm gonna experiment with this. – Vesper Jul 24 '15 at 08:31
  • Was thinking along the lines of `ReadBlock()` on a `StreamReader`, or `Get-Content -Encoding Byte -ReadCount $buffersize`. Make the first check that the underlying streams have the same length (no need to compare if they differ in length) – Mathias R. Jessen Jul 24 '15 at 08:39
  • Yep, one can do the same with filestreams [`[System.IO.FileStream].read()`](https://msdn.microsoft.com/en-us/library/system.io.filestream.read(v=vs.110).aspx), this object also has `length` property to compare. The interesting point would be if the files are needed to be compared as text, therefore streams might have different lengths while text-wise files would be equal (an example: an UTF8 document and its UTF16 dump from another source). This way `ReadAllText()` method should technically return true, while both `ReadAllBytes()` and plain stream content comparison will return false. – Vesper Jul 24 '15 at 08:50
  • 1
    This approach can also open ways for making true `diff` and `patch` in Powershell, even bytewise compatible with those Linux commands as requested here http://stackoverflow.com/questions/30889161/ - one would just need to read and reproduce the diff file format. (Oops wrong link) – Vesper Jul 24 '15 at 08:53
  • Just read about `diff` and `patch` - I expected them to be binary tools, no they are ASCII encoding-unaware tools, and then they could be done in Powershell via plain `Get-Content` and line by line compare, while first throwing verbose `Compare-Object` on them. Hmmm, hmm. – Vesper Jul 24 '15 at 09:00
  • The files are around 50-500 lines in length. Simple text files with minimal data. – Samantha J T Star Jul 24 '15 at 10:07
  • @SamanthaJ If so, there should be no problem running this code as is. – Vesper Jul 24 '15 at 10:43
1

Use like below, fastest and shortest way to compare all type of files:

$(Get-FileHash $file1).hash -eq $(Get-FileHash $file2).hash
0

You could do something like

$file1 = get-content file1 -raw
$file2 = get-content file2 -raw
Compare-Object $file1 $file2 -caseSensitive

That will compare the contents of the files instead. This would work fine on smaller files. If you are working with large files consider using md5 checksum instead. Look at the following post for an example.

The main difference between md5 and reading the entire file into memory is that depend ending on the md5 implementation it is not necessary to hold the entire contents of both files in memory to make the comparison.

Community
  • 1
  • 1
Jower
  • 565
  • 2
  • 8
  • No, `Compare-Object` does not compare for true equality, if used like this. `$s1=@("a","b"); $s2=@("b","a"); compare-object $s1 $s2` returns zero differences, but files (`get-content` returns arrays of strings, so these represent files) are different. Also getting MD5 hashes of files requires reading those files, so this solution is not better than plain comparing file contents. – Vesper Jul 24 '15 at 06:42
  • You are right about the Compare-Object considering the array of strings the same even though the sorting is different. Thanks for clarifying that. I have updated my post and commented some more about md5 scenarios. – Jower Jul 25 '15 at 09:03