我想比较2个文本文件,然后将差异输出到另一个文本文件中。
$Location = "c:\temp\z.txt"
compare-object (get-content c:\temp\hostname_old.txt) (get-content c:\temp\hostname_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
注意:一个输入文件具有重复条目的相关问题是this question的主题。
答案 0 :(得分:1)
只需使用-PassThru parameter:
compare-object (get-content c:\temp\hostname_old.txt) (get-content c:\temp\hostname_new.txt) -PassThru | Out-File $Location
完全满足您的需求。
答案 1 :(得分:0)
更新:Palle Due's helpful answer提供了最佳解决方案。
对于将成员枚举与管道使用进行对比,对输出格式进行讨论以及将Out-File
与Set-Content
进行对比,该答案可能仍然很有意义。
在PSv3 +中,您可以使用member enumeration 提取.InputObject
值:
PS> (Compare-Object (Get-Content old.txt) (Get-Content new.txt)).InputObject
server05
server06
注意:
成员枚举既方便又快速,但以内存消耗为代价,这对于非常大的集合(不是此处)可能是个问题。 Compare-Object
的输出必须作为数组([object[]]
整体存储在存储器 中,并且类似地,.InputObject
属性值作为数组。
对于速度较慢但对内存友好的流(一对一处理),请与Select-Object -ExpandProperty
一起使用 pipeline ,就像TobyU's effective solution一样。
重新保存到文件:将管道输送到Out-File $location
(或更简洁地说,使用输出重定向:> $location
)-不需要Format-List
通常,请注意,Format-*
cmdlet的目的是为 display 生成输出,而不是为程序化处理和持久性生成
也就是说, Out-File
/ >
(有效)使用幕后的Format-*
cmdlet来生成输入对象的字符串表示形式,就像默认的控制台输出,这就是为什么不是用于持久存储任意输入对象的正确命令的原因。
将 Out-File
/ >
与字符串结合使用是安全的,,因为它们是按原样输出的。相反,即使数字具有小数位,偶数也是有问题的,因为它们是用当前区域性的小数点分隔符(例如,,
而不是某些文化中的.
来字符串化的。)
如果您的输入对象是字符串,则可以选择使用Set-Content
,它比Out-File
/ >
快,但需要注意的是,在Windows PowerShell中,默认使用的字符编码不同:Out-File
/ >
默认情况下会生成UTF-16LE文件,而Set-Content
使用旧系统语言环境的“ ANSI”代码页(通常是单字节8位编码,例如Windows-1252)。
相比之下,在PowerShell Core 中,两个cmdlet都生成无BOM的UTF-8。
请注意,Set-Content
与Out-File
不同,仅通过对非字符串对象调用.ToString()
方法即可对它们进行字符串化。
答案 2 :(得分:0)
我猜您正在寻找Select-Object -ExpandProperty InputObject
compare-object (get-content c:\temp\hostname_old.txt) (get-content c:\temp\hostname_new.txt) | Select-Object -ExpandProperty InputObject | Out-File $Location
请注意,在将数据写入文件之前,不能在format-list
中使用Pipeline
。