Powershell 比较6个对象的内容并删除不匹配的内容
我有6个文件是动态创建的,所以我不知道内容。我需要比较这6个文件,确切地说,将一个文件与其他5个文件进行比较,看看文件1中的所有内容与其他5个文件相匹配。应该保存匹配的内容,其他内容需要删除 我编写了如下代码,但正在删除所有匹配的内容Powershell 比较6个对象的内容并删除不匹配的内容,powershell,Powershell,我有6个文件是动态创建的,所以我不知道内容。我需要比较这6个文件,确切地说,将一个文件与其他5个文件进行比较,看看文件1中的所有内容与其他5个文件相匹配。应该保存匹配的内容,其他内容需要删除 我编写了如下代码,但正在删除所有匹配的内容 $lines = Get-Content "C:\snaps.txt" $check1 = Get-Content "C:\Previous_day_latest.txt" $check2 = Get-Content "C:\this_week_saved_sna
$lines = Get-Content "C:\snaps.txt"
$check1 = Get-Content "C:\Previous_day_latest.txt"
$check2 = Get-Content "C:\this_week_saved_snaps.txt"
$check3 = Get-Content "C:\all_week_latest_snapshots.txt"
$check4 = Get-Content "C:\each_month_latest.txt"
$check5 = Get-Content "C:\exclusions.txt"
foreach($l in $lines)
{
if(($l -notmatch $check1) -and ($l -notmatch $check2) -and ($l -notmatch $check3) -and ($l -notmatch $check4))
{
Remove-Item -Path "C:\$l.txt"
}else
{
#nothing
}
}
foreach($ch in $check5)
{
Remove-Item -Path "C:\$ch.txt"
}
6个文件的内容如下所示:
$line
美元支票1
$check2
$3支票
$4支票
5美元支票
我读过关于比较对象的书。但我不确定如何在我的案例中实现,因为所有5个文件的内容都将不同,所有这些内容都应该保存,以免被删除。有人能指导我实现我所说的吗。?非常感谢您的任何帮助。我将创建一个要检查的文件数组,这样您就可以简单地添加新文件,而无需修改脚本的其他部分
我使用where cmdlet,它使用-in条件筛选引用文件中的所有行,并最终覆盖该文件:
$referenceFile = 'C:\snaps.txt'
$compareFiles = @(
'C:\Previous_day_latest.txt',
'C:\this_week_saved_snaps.txt',
'C:\all_week_latest_snapshots.txt',
'C:\each_month_latest.txt',
'C:\exclusions.txt'
)
# get the content of the reference file
$referenceContent = (gc $referenceFile)
foreach ($file in $compareFiles)
{
# get the content of the file to check
$content = (gc $file)
# filter all contents from the file to check which are in the reference file and save it
$content | where { $_ -in $referenceContent } | sc $file
}
我将创建一个要检查的文件数组,这样您就可以简单地添加新文件,而无需修改脚本的其他部分
我使用where cmdlet,它使用-in条件筛选引用文件中的所有行,并最终覆盖该文件:
$referenceFile = 'C:\snaps.txt'
$compareFiles = @(
'C:\Previous_day_latest.txt',
'C:\this_week_saved_snaps.txt',
'C:\all_week_latest_snapshots.txt',
'C:\each_month_latest.txt',
'C:\exclusions.txt'
)
# get the content of the reference file
$referenceContent = (gc $referenceFile)
foreach ($file in $compareFiles)
{
# get the content of the file to check
$content = (gc $file)
# filter all contents from the file to check which are in the reference file and save it
$content | where { $_ -in $referenceContent } | sc $file
}
您可以使用-contains操作符来比较数组内容。如果打开所有要检查并存储到阵列中的文件,可以将其与参考文件进行比较:
$lines = Get-Content "C:\snaps.txt"
$check1 = "C:\Previous_day_latest.txt"
$check2 = "C:\this_week_saved_snaps.txt"
$check3 = "C:\all_week_latest_snapshots.txt"
$check4 = "C:\each_month_latest.txt"
$check5 = "C:\exclusions.txt"
$checklines = @()
(1..5) | ForEach-Object {
$comp = Get-Content $(Get-Variable check$_).value
$checklines += $comp
}
$matches = $lines | ? { $checklines -contains $_ }
如果将-contains切换为-notcontains,您将看到三行不匹配的内容,您可以使用-contains操作符来比较数组内容。如果打开所有要检查并存储到阵列中的文件,可以将其与参考文件进行比较:
$lines = Get-Content "C:\snaps.txt"
$check1 = "C:\Previous_day_latest.txt"
$check2 = "C:\this_week_saved_snaps.txt"
$check3 = "C:\all_week_latest_snapshots.txt"
$check4 = "C:\each_month_latest.txt"
$check5 = "C:\exclusions.txt"
$checklines = @()
(1..5) | ForEach-Object {
$comp = Get-Content $(Get-Variable check$_).value
$checklines += $comp
}
$matches = $lines | ? { $checklines -contains $_ }
如果您将-contains切换为-notcontains,您将看到三行不匹配的内容这里的其他答案非常好,但我想告诉您,Compare对象仍然可以工作。但是,您需要在循环中使用它。为了尝试并展示一些其他的东西,我包含了一个简单的joinpath用法,用于构建检查数组。基本上,当您将文件移动到生产区域时,我们可以节省一些输入。更新一个路径而不是多个路径
$rootPath = "C:\"
$fileNames = "Previous_day_latest.txt", "this_week_saved_snaps.txt", "all_week_latest_snapshots.txt", "each_month_latest.txt", "exclusions.txt"
$lines = Get-Content (Join-path $rootPath "snaps.txt")
$checks = $fileNames | ForEach-Object{Join-Path $rootPath $_}
ForEach($check in $checks){
Compare-Object -ReferenceObject $lines -DifferenceObject (Get-Content $check) -IncludeEqual |
Where-Object{$_.SideIndicator -eq "=="} |
Select-Object -ExpandProperty InputObject |
Set-Content $check
}
因此,我们获取每个文件路径,并在循环中使用Compare对象将每个路径与$lines数组进行比较。使用-IncludeEqual,我们找到两个文件共享的行,并将它们写回文件
根据您有多少检查以及检查的位置,使用此行来构建数组$checks可能更容易
这里的其他答案很好,但我想告诉你们,比较对象仍然可以工作。但是,您需要在循环中使用它。为了尝试并展示一些其他的东西,我包含了一个简单的joinpath用法,用于构建检查数组。基本上,当您将文件移动到生产区域时,我们可以节省一些输入。更新一个路径而不是多个路径
$rootPath = "C:\"
$fileNames = "Previous_day_latest.txt", "this_week_saved_snaps.txt", "all_week_latest_snapshots.txt", "each_month_latest.txt", "exclusions.txt"
$lines = Get-Content (Join-path $rootPath "snaps.txt")
$checks = $fileNames | ForEach-Object{Join-Path $rootPath $_}
ForEach($check in $checks){
Compare-Object -ReferenceObject $lines -DifferenceObject (Get-Content $check) -IncludeEqual |
Where-Object{$_.SideIndicator -eq "=="} |
Select-Object -ExpandProperty InputObject |
Set-Content $check
}
因此,我们获取每个文件路径,并在循环中使用Compare对象将每个路径与$lines数组进行比较。使用-IncludeEqual,我们找到两个文件共享的行,并将它们写回文件
根据您有多少检查以及检查的位置,使用此行来构建数组$checks可能更容易
所以,如果$lines中的一行包含在任何$check中,请保留它,如果没有,请放弃它?哦,如果Vesper是对的,我误解了这个问题。我从文件中删除所有行以检查引用文件中没有的行。如果$line中的一行包含在任何$check中,请保留它,如果没有,请删除它?哦,如果Vesper是对的,我误解了这个问题。我从文件中删除所有行以检查哪些不在参考文件中谢谢。但是我可以删除当时不匹配的文件吗。?或者至少写下与新文件不匹配的名称,以便删除这些名称。我可以看到它现在正在覆盖所有文件。是否要删除空文件?否。我要将那些不匹配的名称写入新文件。然后我可以删除相应的文件。然后您可以使用-notin条件,如:$content | where{$\uUnotin$referenceContent}| sc'notmatching.txt'谢谢。我做了一些更多的编辑,根据需要,它的作品很好。谢谢。但是我可以删除当时不匹配的文件吗。?或者至少写下与新文件不匹配的名称,以便删除这些名称。我可以看到它现在正在覆盖所有文件。是否要删除空文件?否。我要将那些不匹配的名称写入新文件。然后我可以删除相应的文件。然后您可以使用-notin条件,如:$content | where{$\uUnotin$referenceContent}| sc'notmatching.txt'谢谢。根据需要,我做了更多的编辑,效果很好。
$referenceFile = 'C:\snaps.txt'
$compareFiles = @(
'C:\Previous_day_latest.txt',
'C:\this_week_saved_snaps.txt',
'C:\all_week_latest_snapshots.txt',
'C:\each_month_latest.txt',
'C:\exclusions.txt'
)
# get the content of the reference file
$referenceContent = (gc $referenceFile)
foreach ($file in $compareFiles)
{
# get the content of the file to check
$content = (gc $file)
# filter all contents from the file to check which are in the reference file and save it
$content | where { $_ -in $referenceContent } | sc $file
}
$lines = Get-Content "C:\snaps.txt"
$check1 = "C:\Previous_day_latest.txt"
$check2 = "C:\this_week_saved_snaps.txt"
$check3 = "C:\all_week_latest_snapshots.txt"
$check4 = "C:\each_month_latest.txt"
$check5 = "C:\exclusions.txt"
$checklines = @()
(1..5) | ForEach-Object {
$comp = Get-Content $(Get-Variable check$_).value
$checklines += $comp
}
$matches = $lines | ? { $checklines -contains $_ }
$rootPath = "C:\"
$fileNames = "Previous_day_latest.txt", "this_week_saved_snaps.txt", "all_week_latest_snapshots.txt", "each_month_latest.txt", "exclusions.txt"
$lines = Get-Content (Join-path $rootPath "snaps.txt")
$checks = $fileNames | ForEach-Object{Join-Path $rootPath $_}
ForEach($check in $checks){
Compare-Object -ReferenceObject $lines -DifferenceObject (Get-Content $check) -IncludeEqual |
Where-Object{$_.SideIndicator -eq "=="} |
Select-Object -ExpandProperty InputObject |
Set-Content $check
}
$checks = Get-ChildItem "C:\" -Filter "*.txt" | Select-Object -Expand FullName