PowerShell文件比较

22
我正在使用PowerShell脚本在一些服务器上移动一些文件。 我想测试一下要移动的文件是否已经存在于目标位置。 不只是文件名相同。
我认为 Compare-Object $File1 $File2 应该可以做到,但无论文件是什么,它总是返回它们是相同的,例如:
InputObject           SideIndicator                              
-----------           -------------                              
D:\1.gif               =>                                         
D:\1.wma               <=    

还有其他方法可以测试两个文件是否相同吗?


你可以在 PowerShell 中使用 DOS:**fc.exe "file1" "file2"**(注意:必须使用“fc.exe”,因为在 PowerShell 中,“fc”是“format-custom”)。这会给出更少加密的输出。 - Andrew
6个回答

30
(Get-FileHash $path1).Hash -eq (Get-FileHash $path2).Hash

1
这真的比一个年代久远、被接受的解决方案更好吗? - Nico Haase
9
在某些情况下是可以的。正如@Jaykul所说,这取决于你对“相同”的定义。例如:我有两个文件,它们的名称和最后写入时间不同,但它们的内容是相同的。这个解决方案是比使用Get-Content更快且更好的比较两个文件内容的方法(原因与内存相关,在上面已经描述)。 - Stadem

13

我想这将取决于你对“相同”的定义。

Compare-Object (ls Source\Test.*) (ls Dest\Test.*) -Property Name, Length, LastWriteTime

这将按名称、长度和修改日期比较实际的 FILE 对象。添加-IncludeEqual 将导致还显示在两个位置相同的文件。

如果您只想从“源”复制与“目标”不同的文件,请执行以下操作:

Compare-Object (ls $Source) (ls $Destination) -Property Name, Length, LastWriteTime -passthru | 
Where { $_.PSParentPath -eq (gi $Source).PSPath } |
Copy-Item $Destination

不要开始编写获取内容的脚本(正如其他人建议的那样)来进行文件比较——这会将所有内容加载到内存中……

考虑使用robocopy(尽管其命令行语法过时)。=Þ


谢谢,这是我认为我需要走的方向。 - zebidy

7

您只是将两个字符串传递给Compare-Object,您需要文件内容:

Compare-Object (gc $File1) (gc $File2)

同时,您提供的输出并不意味着这些文件是相同的。


如果文件不是文本,则应添加“-Raw”参数到“gc”。 - Serhii Kheilyk

4

comp.exefc.exe有什么问题吗?只需要在调用它们后检查$?以查看命令是否成功即可。


1

您可以这样测试给定路径$path1$path2的文件内容是否相等:

[io.file]::ReadAllText($path1) -eq [io.file]::ReadAllText($path2)

...虽然你也可以选择比较::ReadAllBytes()方法的结果。

说实话,当我只关心复制已更改或添加的文件时,我只使用Robocopy,即使从PowerShell中执行。


1
是的,我开始使用Robocopy,但不幸的是发现它不能满足我的要求。显然,这是一个常见的解决方案,因为我在谷歌上找到的所有内容似乎都指向RoboCopy。 - zebidy
1
只是出于好奇,Robocopy在哪方面不能满足您的要求? - kbrimington
注意这个方法:你正在将两个文件完全加载到内存中,然后进行比较... = 非常占用内存。 - Davor Josipovic

1
compare $file1 $file2 -includeequal -excludedifferent

2
这比较的是两个字符串,而不是文件内容。 - Lars Truijens

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接