Powershell Or Python3 - CSV-файл: удалить строку на основе дубликатов в столбце, с условиями на основе IF ELSE в другом столбце - PullRequest
0 голосов
/ 06 апреля 2020

Так что я немного слаб в своем кодировании и имею некоторый опыт работы с powershell и python, поэтому я открыт для решений в любом из них.

Это может быть сложно описать, поэтому я создал поддельный набор данных в надежде, что это сделает это более ясным.

Что я пытаюсь сделать, так это дедуплицировать строки каждого CSV в каталоге на основе имени, но затем по порядку: Если NARRATIVE = "CAUGHT", я хочу сохранить эта строка еще, если NARRATIVE содержит URL, я хочу сохранить эту строку, если ни одна из них не является истинной, я хочу сохранить последнюю / самую нижнюю запись.

Мне кажется, что я ближе всего к PowerShell, поэтому я Я буду использовать этот пример, но если вы сможете решить эту проблему в python, я также полностью открыт для этого. Где я терплю неудачу здесь?

gci -Filter *.csv | Select-Object -ExpandProperty FullName | Import-Csv | Foreach-Object {Select-Object where $_.NARRATIVE -Contains "Caught"} | export-csv test1.csv -NoTypeInformation

Основной набор данных:

SITE,DATE,URL,SITE2,NAME,NARRATIVE
AAA,03/17/2020,https://someurl.com/1234,BBB,NAME1,CAUGHT
AAA,03/17/2020,https://someurl.com/1234,BBB,NAME2,CAUGHT
AAA,03/17/2020,https://someurl.com/1234,BBB,NAME3,CAUGHT
AAA,03/17/2020,https://someurl.com/1234,BBB,NAME4,CAUGHT
AAA,03/17/2020,https://someurl.com/1234,BBB,NAME5,CAUGHT
AAA,03/17/2020,https://someurl.com/1234,BBB,NAME6,CAUGHT
AAA,03/17/2020,https://someurl.com/1234,BBB,NAME7,CAUGHT
AAA,03/17/2020,https://someurl.com/1234,BBB,NAME1,only visited http://thisismyhouse.com once
AAA,03/17/2020,https://someurl.com/1234,BBB,NAME2,NAME2 did some stuff and here's how/why
AAA,03/17/2020,https://someurl.com/1234,BBB,NAME5,NAME5 just sat there
AAA,03/17/2020,https://someurl.com/1234,BBB,NAME3,NAME3 was really important right here
AAA,03/17/2020,https://someurl.com/1234,BBB,NAME6,NAME6 fell down and couldn’t get up
AAA,03/17/2020,https://someurl.com/1234,BBB,NAME3,NAME3 was MOST important right here
AAA,03/17/2020,https://someurl.com/1234,BBB,NAME8,NAME8 Dropped the beat
AAA,03/17/2020,https://someurl.com/1234,BBB,NAME9,After the game NAME9 went home
AAA,03/17/2020,https://someurl.com/1234,BBB,NAME4,"while NAME4 was at the store, they found a grape"
AAA,03/17/2020,https://someurl.com/1234,BBB,NAME7,NAME7 got hit in the head
AAA,03/17/2020,https://someurl.com/1234,BBB,NAME9,NAME9 spends a lot of time on http://dungeondepths.com
AAA,03/17/2020,https://someurl.com/1234,BBB,NAME1,On Friday the 13th NAME1 got a tattoo
AAA,03/17/2020,https://someurl.com/1234,BBB,NAME4,For dinner NAME4 ordered pizza
AAA,03/17/2020,https://someurl.com/1234,BBB,NAME8,NAME8 Fired the Bass Cannon
AAA,03/17/2020,https://someurl.com/1234,BBB,NAME9,NAME9 is rebooting
AAA,03/17/2020,https://someurl.com/1234,BBB,NAME6 ,NAME6 broke their leg
AAA,03/17/2020,https://someurl.com/1234,BBB,NAME8,NAME8 Put the needle on the record

Желаемые результаты:

SITE,DATE,URL,SITE2,NAME,NARRATIVE
AAA,03/17/2020,https://someurl.com/1234,BBB,NAME1,CAUGHT
AAA,03/17/2020,https://someurl.com/1234,BBB,NAME2,CAUGHT
AAA,03/17/2020,https://someurl.com/1234,BBB,NAME3,CAUGHT
AAA,03/17/2020,https://someurl.com/1234,BBB,NAME4,CAUGHT
AAA,03/17/2020,https://someurl.com/1234,BBB,NAME5,CAUGHT
AAA,03/17/2020,https://someurl.com/1234,BBB,NAME6,CAUGHT
AAA,03/17/2020,https://someurl.com/1234,BBB,NAME7,CAUGHT
AAA,03/17/2020,https://someurl.com/1234,BBB,NAME9,NAME9 spends a lot of time on http://dungeondepths.com
AAA,03/17/2020,https://someurl.com/1234,BBB,NAME8,NAME8 Put the needle on the record

1 Ответ

2 голосов
/ 06 апреля 2020

Теперь, когда я полностью понимаю, попробуйте это (имея еще пару предположений):

$groupedCsv = Import-Csv .\stackTest.csv | Group-Object Name
$result = @()
foreach ($csvObject in $groupedCsv){
    if($value = $csvObject | % {$_.Group | Where-Object Narrative -eq "Caught"}){
        $result += $value
    } elseif ($value = $csvObject | % {$_.Group | Where-Object Narrative -like "*http*"}){
        $result += $value
    } else {
        $result += $csvObject.Group[-1]
    }

}

#This is just to show the result
$result | ft

Допущения:

  1. Из каждой группы имен будет выполнено только одно условие и я буду уважать заказ, который вы дали.

После этого я получу ваш результат.

Я надеюсь, что это решит вашу проблему. И если вы хотите запустить это с несколькими CSV, я рекомендую создать это как функцию и вызывать ее для каждого CSV, чтобы не сделать логику c более сложной, чем должна быть, а также чтобы ее можно было использовать повторно, например:

function Parse-Csv{
    Param(
        [Parameter(Mandatory=$true, ValueFromPipelineByPropertyName=$true)]
        [Alias("Path")]
        [String] $FullName
    )
    process{
        if(Test-Path -Path $FullName -IsValid){
            #SetUp
            $groupedCsv = Import-Csv -Path $FullName | Group-Object Name
            $result = @()

            #Main
            foreach ($csvObject in $groupedCsv){
                if($value = $csvObject | % {$_.Group | Where-Object Narrative -eq "Caught"}){
                    $result += $value
                } elseif ($value = $csvObject | % {$_.Group | Where-Object Narrative -like "*http*"}){
                    $result += $value
                } else {
                    $result += $csvObject.Group[-1]
                }
            }
            $result | Export-Csv -Path $FullName -Force -NoTypeInformation
        } else{
            Write-Error "Invalid path provided ($Path), please verify and try again."
        }
    }
}

gci -Filter *.csv | Parse-Csv
...