none
Удаление дубликатов строк при попарном чтении строк RRS feed

  • Вопрос

  • Добрый день!

    Есть плейлисты (по сути текстовые файлы) с дублирующимися строками:

    #EXTM3U
    #EXTINF:-1,A1
    http://ott-cdn.ucom.am/s45/04.m3u8
    #EXTINF:-1,A2
    http://ott-cdn.ucom.am/s33/04.m3u8
    #EXTINF:-1,Food
    http://ott-cdn.ucom.am/s18/04.m3u8
    #EXTINF:-1,Bridge TV
    http://ott-cdn.ucom.am/s34/04.m3u8
    #EXTINF:-1,Bridge TV Русский хит
    http://ott-cdn.ucom.am/s78/04.m3u8
    #EXTINF:-1,Fine Living
    http://ott-cdn.ucom.am/s51/04.m3u8
    #EXTINF:-1,A12
    http://ott-cdn.ucom.am/s45/04.m3u8
    #EXTINF:-1,Fine Living
    http://ott-cdn.ucom.am/s51/04.m3u8
    #EXTINF:-1,A22
    http://ott-cdn.ucom.am/s33/04.m3u8
    #EXTINF:-1,Food Network
    http://ott-cdn.ucom.am/s18/04.m3u8
    #EXTINF:-1,MCM TOP
    http://ott-cdn.ucom.am/s49/04.m3u8

    Нужно удалить дубликаты строк, но при этом строки должны считываться парами - название канала/ссылка.

    Удалить полные дубликаты пар строк, в моём примере это:

    #EXTINF:-1,Fine Living
    http://ott-cdn.ucom.am/s51/04.m3u8

    можно достаточно просто, к примеру, таким кодом:

    $list = 'C:\old.m3u'
    
    @(for($i, $arr = 0, (gc $list -Encoding default); $i -lt $arr.Length;) {
    $a, $b = $arr[$i], $arr[$i + 1]
    if ($a.StartsWith('#EXTINF') -and $b -match ':\/\/') {
    	"$a`n$b"
    	$i += 2
    }
    else {
    	++$i
    	continue
    }
    }) | Sort-Object -Unique

    Но как удалить пары строк, где одинаковые только ссылки, в примере это:

    #EXTINF:-1,Food
    http://ott-cdn.ucom.am/s18/04.m3u8
    #EXTINF:-1,A12
    http://ott-cdn.ucom.am/s45/04.m3u8
    #EXTINF:-1,A22
    http://ott-cdn.ucom.am/s33/04.m3u8

    Подскажите, пожалуйста, возможно ли удаление таких дубликатов строк кодом Powershell ?

    В итоговом файле должно быть:

    #EXTM3U
    #EXTINF:-1,A1
    http://ott-cdn.ucom.am/s45/04.m3u8
    #EXTINF:-1,A2
    http://ott-cdn.ucom.am/s33/04.m3u8
    #EXTINF:-1,Bridge TV
    http://ott-cdn.ucom.am/s34/04.m3u8
    #EXTINF:-1,Bridge TV Русский хит
    http://ott-cdn.ucom.am/s78/04.m3u8
    #EXTINF:-1,Fine Living
    http://ott-cdn.ucom.am/s51/04.m3u8
    #EXTINF:-1,Food Network
    http://ott-cdn.ucom.am/s18/04.m3u8
    #EXTINF:-1,MCM TOP
    http://ott-cdn.ucom.am/s49/04.m3u8

    Директива #EXTM3U большой роли не играет, её можно будет добавить и потом.

    Заранее благодарен за ответы и подсказки!

    14 марта 2020 г. 7:02

Ответы

  • Виноват, не вниманительно вник в условия.

    $Path = 'd:\tmp\play.txt'
    
    $VerbosePreference = 'Continue'
    $Strings = Select-String -Path D:\tmp\play.txt -Pattern '#EXTINF:' -Context 0,1 
    Write-Verbose "Playlists: $($Strings.Count)"
    
    $AllPl = $Strings | ForEach-Object {
        # Write-Verbose $_
        New-Object PSObject -Property @{ 
            Name = $_.Line
            Link = $_.Context.PostContext[0]
        }
    }
    Write-Verbose "Playlist objects: $($AllPl.Count)"
    $UniqByLink = $AllPl | group Link | foreach {
        $_.Group[0]
    }
    Write-Verbose "UniqByLink: $($UniqByLink.Count)"
    
    $txt = $UniqByLink | foreach {
        @"
    $($_.Name)
    $($_.Link)
    "@
    }
    
    Write-Verbose "Save to file $($Path).unique"
    $FileConent = '#EXTM3U', $txt
    
    $FileConent | Out-File -FilePath "$($Path).unique"
    

    Так верный результат получается?


    Грамотная постановка вопроса - уже 50% решения.
    SCCM User Group Russia на FaceBook и в Telegram

    • Помечено в качестве ответа Uragan66 14 марта 2020 г. 16:36
    14 марта 2020 г. 15:56

Все ответы

  • День добрый.

    Как вариант влоб:

    $Path = 'd:\tmp\play.txt' $VerbosePreference = 'Continue' $Strings = Select-String -Path D:\tmp\play.txt -Pattern '#EXTINF:' -Context 0,1 Write-Verbose "Playlists: $($Strings.Count)" $AllPl = $Strings | ForEach-Object { @" $($_.Line) $($_.Context.PostContext) "@ } Write-Verbose "All List: $($AllPl.Count)" $UniqPl = $AllPl | Select-Object -Unique Write-Verbose "Unique List: $($UniqPl.Count)"

    Write-Verbose "Save to file $($Path).unique"
    $FileConent = ,'#EXTM3U', $UniqPl

    $FileConent | Out-File -FilePath "$($Path).unique"


    Грамотная постановка вопроса - уже 50% решения.
    SCCM User Group Russia на FaceBook и в Telegram



    14 марта 2020 г. 13:39
  • Sergey Korotkov, спасибо большое!

    Но, к сожалению, Ваш код тоже удалил только полные дубли пары строк.

    Строки, где дублируются ссылки остались:

    #EXTINF:-1,A1
    http://ott-cdn.ucom.am/s45/04.m3u8
    #EXTINF:-1,A12
    http://ott-cdn.ucom.am/s45/04.m3u8
    #EXTINF:-1,A2
    http://ott-cdn.ucom.am/s33/04.m3u8
    #EXTINF:-1,A22
    http://ott-cdn.ucom.am/s33/04.m3u8
    #EXTINF:-1,Food Network
    http://ott-cdn.ucom.am/s18/04.m3u8
    #EXTINF:-1,Food
    http://ott-cdn.ucom.am/s18/04.m3u8
    с них нужно оставить только по одной паре - имя канала/ссылка

    14 марта 2020 г. 14:25
  • Виноват, не вниманительно вник в условия.

    $Path = 'd:\tmp\play.txt'
    
    $VerbosePreference = 'Continue'
    $Strings = Select-String -Path D:\tmp\play.txt -Pattern '#EXTINF:' -Context 0,1 
    Write-Verbose "Playlists: $($Strings.Count)"
    
    $AllPl = $Strings | ForEach-Object {
        # Write-Verbose $_
        New-Object PSObject -Property @{ 
            Name = $_.Line
            Link = $_.Context.PostContext[0]
        }
    }
    Write-Verbose "Playlist objects: $($AllPl.Count)"
    $UniqByLink = $AllPl | group Link | foreach {
        $_.Group[0]
    }
    Write-Verbose "UniqByLink: $($UniqByLink.Count)"
    
    $txt = $UniqByLink | foreach {
        @"
    $($_.Name)
    $($_.Link)
    "@
    }
    
    Write-Verbose "Save to file $($Path).unique"
    $FileConent = '#EXTM3U', $txt
    
    $FileConent | Out-File -FilePath "$($Path).unique"
    

    Так верный результат получается?


    Грамотная постановка вопроса - уже 50% решения.
    SCCM User Group Russia на FaceBook и в Telegram

    • Помечено в качестве ответа Uragan66 14 марта 2020 г. 16:36
    14 марта 2020 г. 15:56
  • Да, теперь всё отлично!

    Большое спасибо за помощь!

    14 марта 2020 г. 16:36