【问题标题】:Delete duplicate rows and keep the newest entry删除重复行并保留最新条目
【发布时间】:2018-06-11 14:46:04
【问题描述】:

我每天下载一个.csv 文件,在将它用于其他软件之前,我需要对其进行一些清理。

该文件包含有关在餐馆进行的控制的数据,其中新的控制会导致文件中出现新的一行,这意味着每家餐馆可以有多个条目 - 我只需要最新的。

这是.csv 文件的一部分(仅包含其中的 4 列):

标题

orgnummer;navn;dato;total_karakter

4 个随机行

985129576;Økern Sushi;21092016;1
785423684;Å cafe;09072017;2
458792365;Varangerkroa;01012018;0
985129576;Økern Sushi;05052018;0

orgnummernavn 对于每家餐厅都是独一无二的。

在我的示例中,脚本应该删除 Økern Sushi 的顶部条目。

到目前为止我的脚本:

$temp = Import-Csv 'C:\Users\Downloads\tilsynPS.csv' -Delimiter ';'

#change date format to desired format

foreach($row in $temp) {
    $year = $row.dato.Substring($row.dato.Length - 4, 4)
    $month = $row.dato.Substring($row.dato.Length - 6, 2)
    $day = $row.dato.Substring(0, $row.dato.Length - 6)
    $date = New-Object System.DateTime $year,$month,$day
    $row.dato = $date
}

#Here's my attempt at sorting and deleting old records:

sort orgnummer, dato -Descending

$temp[0]

for ($i=1; $i -le $temp.length -1; $i++)  {
 if ($temp[$i]."orgnummer" -eq $temp[$i-1]."orgnummer"){
   continue
 }
 else {$temp[$i]}

}

#export to csv

$temp | Export-Csv -Encoding UTF8 -NoTypeInformation -path C:\Users\Downloads\tilsynPS_redigert.csv

删除旧记录的尝试基于此帖子:http://community.idera.com/powershell/ask_the_experts/f/powershell_for_windows-12/8073/csv-remove-unique-records-based-on-columns-and-last-date

也试过这个版本的代码:

sort -Property @{Expression="dato";Descending=$true},
@{Expression="navn";Descending=$false}

$temp[0]

for ($i=1; $i -le $temp.length -1; $i++)  {
 if ($temp[$i]."navn" -eq $temp[$i-1]."navn"){
   continue
 }
 else {$temp[$i]}

}

这是我在 PowerShell 中的第一个脚本,非常感谢任何帮助。已经注意到类似的问题,但在我正在使用的 PowerShell 中都没有。

【问题讨论】:

    标签: powershell csv


    【解决方案1】:

    我想你几乎拥有它。此解决方案将结果累积在一个新数组中并将其导出。仅当 orgnummer 不同或它们持有的日期较新时才会添加行。

    请注意,为了进行测试,我必须更改导入和导出文件的路径。

    $temp = Import-Csv "$PSScriptRoot\tilsynPS.csv" -Delimiter ';'
    
    #change date format to desired format
    foreach($row in $temp) {
        $year = $row.dato.Substring($row.dato.Length - 4, 4)
        $month = $row.dato.Substring($row.dato.Length - 6, 2)
        $day = $row.dato.Substring(0, $row.dato.Length - 6)
        $row.dato = New-Object System.DateTime $year,$month,$day
    }
    
    # sort on orgnummer and date descending:
    $temp = $temp | Sort-Object orgnummer, dato -Descending
    
    # create a new array for the output and add the first entry in it already
    $newData = @($temp[0])
    # for all other rows in the array, check if they should be added or not
    for ($i = 1; $i -le $temp.Length -1; $i++)  {
        if ($temp[$i]."orgnummer" -eq $temp[$i-1]."orgnummer" -and $temp[$i]."dato" -le $temp[$i-1]."dato") {
            continue
        }
        else { 
            $newData += $temp[$i] 
        }
    }
    
    #export to csv
    $newData | Export-Csv -Encoding UTF8 -NoTypeInformation -path "$PSScriptRoot\tilsynPS_redigert.csv"
    

    【讨论】:

    • 附注要转换 csv 中的“dato”字符串,您还可以使用 $row.dato = [DateTime]::ParseExact($row.dato, 'ddMMyyyy', $null)
    • 好的,我会调查的。我在找到转换 dato 字段的方法时遇到了一些麻烦,因为它在 .csv 中有一种奇怪/不一致的格式。大部分都是用ddmmyyyy写的,但也有出入,就是说有些条目写的是dmmyyyy,少了第一个“0”。
    • 嗨 Einar,在这种情况下,我会这样做:$row.dato = [DateTime]::ParseExact(('{0:D8}' -f [int]$row.dato), 'ddMMyyyy', $null),只是为了确保在这些情况下添加前导零
    猜你喜欢
    • 1970-01-01
    • 2020-07-05
    • 2020-07-08
    • 2019-04-29
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多