我想比较两个文本文件,并在另一个文本文件中输出差异。
$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-File
与Set-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()
方法来字符串化它们。