从另一个.csv(windows、powershell、notepad++)中删除一个.csv中存在的行
我有notepad++、powershell和Excel2007。我有两个名为.csv的文件 database.csv和import.csv。Import.csv包含我要放置的新条目 在线输入我的数据库。Database.csv包含该数据库中的当前记录。 这两个文件都包含一个简单的逗号-换行符分隔的唯一值列表 但是,数据库可能已经在新文件中包含一些条目。还有,新的 文件包含不在数据库中的条目。并且,数据库文件包含 仍保留用于记录的条目,但不在输入文件中 只要将它们简单地结合起来,就会产生任何持续存在的记录的副本。 它还导致记录的单个副本仅存在于数据库中,而记录仅存在于数据库中 显示在输入文件中 我想要的是一个只包含只存在于输入文件中的记录的文件。 有什么建议吗?Powershell:从另一个.csv(windows、powershell、notepad++)中删除一个.csv中存在的行,powershell,csv,notepad++,Powershell,Csv,Notepad++,我有notepad++、powershell和Excel2007。我有两个名为.csv的文件 database.csv和import.csv。Import.csv包含我要放置的新条目 在线输入我的数据库。Database.csv包含该数据库中的当前记录。 这两个文件都包含一个简单的逗号-换行符分隔的唯一值列表 但是,数据库可能已经在新文件中包含一些条目。还有,新的 文件包含不在数据库中的条目。并且,数据库文件包含 仍保留用于记录的条目,但不在输入文件中 只要将它们简单地结合起来,就会产生任何持续
Get-Content <database file> -TotalCount 1 |
Set-Content C:\somedir\ToUpload.csv
$import = @{}
Get-Content <import file> |
select -Skip 1
foreach {
$import[$_] = $true
}
Get-Content <Database file> |
select -Skip 1 |
foreach {
if ($import[$_])
{
$import[$_].remove()
}
}
$import.Keys |
Add-Content C:\Somedir\ToUpload.csv
或者,将两个文件读入内存:
Get-Content <database file> -TotalCount 1 |
Set-Content C:\somedir\ToUpload.csv
$import = Get-Content <import file>
select -Skip 1
$database = Get-Content <database file>
select -Skip 1
$import |
where {$database -notcontains $_} |
Add-Content C:\somedir\ToUpload.csv
使用导入/导出csv的解决方案可以工作,但与将文件作为文本数据处理相比,会增加额外的内存和处理开销。差异可能很小,也可能很大,具体取决于文件的大小和csv文件中的列数。IMHO.假设您的csv文件包含a、b和c列:
$db = Import-Csv database.csv
$import = Import-Csv import.csv
$new = Compare-Object -ReferenceObject $db -DifferenceObject $import -Property a,b,c -PassThru | ? { $_.SideIndicator -eq "=>" } | Select a,b,c
只需将a、b和c替换为要比较的列的名称即可如果没有任何特定属性可匹配,则比较对象有时会与从csv导入的customobject发生冲突
如果您想要大型csv文件的性能,可以尝试以下方法:
$i = @{}
[IO.File]::ReadAllLines("C:\input.csv") | % { $i[$_] = $true }
$reader = New-Object System.IO.StreamReader "C:\db.csv"
#Skip header. This way the output file(new.csv) will get input.csv's header
$reader.ReadLine() | Out-Null
while (($line = $reader.ReadLine()) -ne $null) {
#Remove row if it exists in db.csv
if ($i.ContainsKey($line)) {
$i.Remove($line)
}
}
$reader.Close()
$i.Keys | Add-Content c:\new.csv
是否有使该行在文件中唯一的列?身份证件first+lastname?至少对我来说,这不适用于csv对象。此外,这也将从$db返回新行,但他没有这样做want@Graimer:你说得对,我没有测试过,那是记忆造成的。我刚刚用一个经过测试的解决方案更新了我的答案。如果你想在大文件上寻找性能,你应该避免将内容放在一起=我认为这取决于应用程序和如何使用get content。比较[IO.File]::ReadAllLines以获取内容-ReadCount 0.ofc,但对于较大的文件,获取内容的速度较慢,句号。默认情况下,它较慢,因为它正在读取内容并构建数组。如果您不需要数组,请使用ReadCount 0,或者如果您希望流式传输并使用V3,请使用-Raw开关。[IO.File]::ReadAllLinespath也会构建数组,但只构建字符串数组,并且运行速度更快。这取决于你需要什么。支持添加noteproperties,但如果您只需要字符串数组,IO.File或StreamReader通常会更快。至少这是我的经历