比较两个文本文件,并将差异写入文本文件



我想比较两个文本文件,并在另一个文本文件中输出差异。

$Location = "c:tempz.txt"
compare-object (get-content c:temphostname_old.txt) (get-content c:temphostname_new.txt) | format-list | Out-File $Location

hostname_old.txt

server02
server05
server04
server06
server01

hostname_new.txt

server04
server01
server02

结果

InputObject   : server05
SideIndicator : <=
InputObject   : server06
SideIndicator : <=

这就是我想要的:(去掉InputObject和SideIndicator)

server05
server06

注意:一个输入文件有重复条目的相关问题就是这个问题的主题。

只需使用-PassThru参数:

compare-object (get-content c:temphostname_old.txt) (get-content c:temphostname_new.txt) -PassThru | Out-File $Location

做你想做的事。

我猜您正在寻找Select-Object -ExpandProperty InputObject

compare-object (get-content c:temphostname_old.txt) (get-content c:temphostname_new.txt) | Select-Object -ExpandProperty InputObject | Out-File $Location

请注意,在将数据写入文件之前,不能在Pipeline中使用format-list

更新:Palle Due的有用答案提供了最佳解决方案
对于将成员访问枚举与管道使用进行对比、讨论输出格式以及将Out-FileSet-Content进行对比,此答案可能仍然很有意义。


在PSv3+中,您可以简单地使用成员访问枚举来提取.InputObject值:

PS> (Compare-Object (Get-Content old.txt) (Get-Content new.txt)).InputObject
server05
server06

注:

  • 成员访问枚举方便快捷,但以内存消耗为代价,这可能是非常大的集合的问题(此处没有)。Compare-Object的输出必须作为一个数组([object[]])中的一个整体收集在内存中,并且类似地,.InputObject属性值作为一个阵列返回。

  • 对于较慢但内存友好的流式传输(逐个处理),请将管道Select-Object -ExpandProperty一起使用,就像TobyU的有效解决方案一样。

Re保存到文件:管道到Out-File $location(或者更简洁地说,使用输出重定向:> $location)就足够了-不需要Format-List

通常,请注意,Format-*cmdlet的目的是为显示生成输出,而不是用于编程处理和持久性。

也就是说,Out-File/>(有效地)在后台使用Format-*cmdlet来生成输入对象的字符串表示,就像默认的控制台输出一样,这就是为什么它不是持久化任意输入对象的正确命令

Out-File/>字符串一起使用是安全的,但是,因为它们是按原样输出的。相比之下,偶数如果有小数位数,则会有问题,因为它们是用当前区域性的十进制分隔符字符串化的(例如,在某些区域性中,,而不是.)。

如果您的输入对象是字符串,您也可以使用Set-Content,它比Out-File/>更快,但需要注意的是,在Windows PowerShell中,默认使用的字符编码不同:默认情况下,Out-File/>生成UTF-16LE文件,而Set-Content使用传统系统区域设置的";ANSI";代码页(通常是诸如Windows-1252的单字节8位编码)
相比之下,在PowerShellCore中,两个cmdlet都生成无BOM的UTF-8。

请注意,与Out-File不同,Set-Content只是通过对非字符串对象调用.ToString()方法来字符串化它们。

相关内容

  • 没有找到相关文章