Имя пользователя:
Пароль:  
Помощь | Регистрация | Забыли пароль?  | Правила  

Компьютерный форум OSzone.net » Программирование, базы данных и автоматизация действий » Скриптовые языки администрирования Windows » Любой язык - [решено] Удаление дубликатов строк из текстового файла со сравнением по две строки

Ответить
Настройки темы
Любой язык - [решено] Удаление дубликатов строк из текстового файла со сравнением по две строки

Старожил


Сообщения: 216
Благодарности: 15

Профиль | Отправить PM | Цитировать


Доброго времени суток всем.
Знаю что тема уже изъезжена, но готового решения найти не получается.
Есть плейлисты (по сути текстовые файлы), при их создании может получаться большое количество дублирующих строк.
Например:
Код: Выделить весь код
#EXTINF:0, 1+1
http://193.106.211.2:1234/udp/225.1.1.103:4001
#EXTINF:0, ICTV
http://193.106.211.2:1234/udp/225.1.1.104:4001
#EXTINF:0, 5 канал
http://193.106.211.2:1234/udp/225.1.1.105:4001
#EXTINF:0, СТБ
http://193.106.211.2:1234/udp/225.1.1.106:4001
#EXTINF:0, ТРК «Украина»
http://193.106.211.2:1234/udp/225.1.1.107:4001
#EXTINF:0, Сити
http://193.106.211.2:1234/udp/225.1.1.108:4001
#EXTINF:0, Тонис
http://193.106.211.2:1234/udp/225.1.1.111:4001
#EXTINF:0, ТЕТ
http://193.106.211.2:1234/udp/225.1.1.110:4001
#EXTINF:0, ТРК «Киев»
http://193.106.211.2:1234/udp/225.1.1.114:4001
#EXTINF:0, Тонис
http://193.106.211.2:1234/udp/225.1.1.111:4001
#EXTINF:0, Мега
http://193.106.211.2:1234/udp/225.1.1.112:4001
#EXTINF:0, М1
http://193.106.211.2:1234/udp/225.1.1.113:4001
#EXTINF:0, канал «Киев»
http://193.106.211.2:1234/udp/225.1.1.114:4001
#EXTINF:0, 2+2
http://193.106.211.2:1234/udp/225.1.1.115:4001
#EXTINF:0, ТРК «Украина»
http://190.106.210.2:1234/udp/225.1.1.107:4001
Строки обязательно должны считываться попарно: название канала - адрес потока. В примере три дубликата, в первом повторяются и название и адрес, во втором - только адрес, в третьем - только название. Из этих дублирующихся строк нужно удалить только те, где повторяются и название и адрес, то есть в примере только первую пару.
Пересмотрел кучу различных скриптов, сам пробовал батники писать, но все они считывают по одной строке и в выходном файле может получится к названию канала несколько адресов или наоборот.
К примеру такой батник:
Код: Выделить весь код
@echo off
setlocal disableDelayedExpansion
set "file=%~1"
set "line=%file%.line"
set "deduped=%file%.deduped"
::Define a variable containing a linefeed character
set LF=^


::The 2 blank lines above are critical, do not remove
>"%deduped%" (
  for /f usebackq^ eol^=^%LF%%LF%^ delims^= %%A in ("%file%") do (
    set "ln=%%A"
    setlocal enableDelayedExpansion
    >"%line%" (echo !ln:\=\\!)
    >nul findstr /xlg:"%line%" "%deduped%" || (echo !ln!)
    endlocal
  )
)
>nul move /y "%deduped%" "%file%"
2>nul del "%line%"
в выходном файле делает так:
Код: Выделить весь код
#EXTINF:-1  group-title="Познавательные",Brodilo.TV
http://brodilo.tv/channel.php
#EXTINF:-1  group-title="Познавательные",Da Vinci Learning
http://hls.peers.tv/streaming/da_vinci/16/tvrecw/playlist.m3u8|User-Agent=DuneHD/1.0.3
http://194.28.155.10:81/udp/225.0.55.26:1234
#EXTINF:-1  group-title="Прочие каналы:",112 Украина 
#EXTINF:-1  group-title="Прочие каналы:",112 Украина HD
http://112hd-hls3.cosmonova.net.ua/hls/112hd_ua_mid/index.m3u8
http://app.live.112.events/hls-ua/112hd_mid/index.m3u8
#EXTINF:-1  group-title="Прочие каналы:",112 Украина [FHD]
#EXTINF:-1  group-title="Прочие каналы:",112 Україна
#EXTINF:-1  group-title="Прочие каналы:",112 Україна HD
#EXTINF:-1  group-title="Прочие каналы:",12 Канал (Омск)
http://12channel.bonus-tv.ru:80/stream549837052987/tracks-v1a1/mono.m3u8
#EXTINF:-1  group-title="Познавательные",Discovery Channel
http://st6.allplay.uz/iptv/4/index.m3u8
#EXTINF:-1  group-title="Познавательные",Discovery Channel HD
http://st6.allplay.uz/iptv/74/index.m3u8
Это отрывок из другого плейлиста, он слишком длинный для помещения в пример.
Другие скрипты делают аналогично.
Они сравнивают по одной строке.
Может кто подскажет как реализовать сравнивание строк попарно, чтобы не нарушалась структура плейлиста ?
Премного буду благодарен за помощь.

Отправлено: 23:26, 26-06-2019

 

Забанен


Сообщения: 793
Благодарности: 260

Профиль | Цитировать


Цитата YuS_2:
тоже есть параметр -Unique
Ага, но в виду редкости его использования на практике, о нем легко позабыть.

Отправлено: 18:25, 27-06-2019 | #11



Для отключения данного рекламного блока вам необходимо зарегистрироваться или войти с учетной записью социальной сети.

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


Старожил


Сообщения: 216
Благодарности: 15

Профиль | Отправить PM | Цитировать


По ходу работы со скриптом, выяснились некоторые нюансы. Для скрипта, предложенного ув. Iska:
Цитата Iska:
Код: Выделить весь код
$aContent = Get-Content -Path 'C:\Мои проекты\0266\0001.txt'

 @(for($i = 0; $i -le $aContent.Length - 1; $i = $i + 2) {
 $aContent[$i] + "`r`n" + $aContent[$i + 1]
}) | Sort-Object -Unique
»
требуются идеальные пары строк: название канала - ссылка. И соответственно чётное количество строк.
В противном случае строки могут перемешаться, и ссылки не будут соответствовать.
Бывает попадаются файлы с различного рода мусором между строк. К примеру:
Код: Выделить весь код
#EXTINF:-1 ,Первый канал
http://gorod.tv/s/live/1/46.252.219.59/1561632042766/0.m3u8
#EXTINF:-1 ,Россия 1
http://gorod.tv/s/live/2/46.252.219.59/1561632042766/0.m3u8
#EXTINF:-1 ,Матч ТВ
http://gorod.tv/s/live/3/46.252.219.59/1561632042766/0.m3u8
#EXTINF:-1 ,НТВ
http://gorod.tv/s/live/4/46.252.219.59/1561632042766/0.m3u8
#EXTINF:-1 ,Пятый канал
http://gorod.tv/s/live/5/46.252.219.59/1561632042766/0.m3u8
Здесь какая-то информация
http://gorod.tv/s/live/1/46.252.219.59/1561632042766/0.m3u8
#EXTINF:-1 ,Пятый канал
#EXTINF:-1 ,Россия К
http://gorod.tv/s/live/6/46.252.219.59/1561632042766/0.m3u8
#EXTINF:-1 , Москва 24
http://91.231.219.145:80/tv_moscow_24/video.m3u8
#EXTINF:-1 , Санкт-Петербург
http://91.231.219.145:80/tv_sankt_peterburg/video.m3u8
https://smarttvnews.ru/wp-content/uploads/2018/11/BT-2016-logo_color7890.png
https://smarttvnews.ru/wp-content/uploads/2018/11/BT-2016-logo_color7890.png
#EXTINF:-1 ,Discovery
http://hls-v3-spbtv.msk.spbtv.com/for_spb/msk/ipv3/154.m3u8
#EXTINF:-1 ,NASA TV
http://hls-v3-spbtv.msk.spbtv.com/for_spb/msk/ipv3/17.m3u8
#EXTINF:-1 ,Россия 24
http://gorod.tv/s/live/7/46.252.219.59/1561632042766/0.m3u8
#EXTINF:-1 ,Карусель
http://gorod.tv/s/live/8/46.252.219.59/1561632042766/0.m3u8
В примере вместо названия канала может быть что-то другое написано или канал может быть без ссылки. Или же прописаны ссылки на изображения.

Можно ли, перед выполнением основного кода скрипта, как-то удалить всё, что не соответствует парам канал - ссылка ? Регулярным выражением или дополнительным кодом в скрипт.
То есть первая строка название канала, обязательно начинающееся на #EXTINF, вторая строка - обязательно ссылка (могут быть http; https; rtmp; mms; rtmpe; udp).
Всё что не соответствует таким парам нужно удалить.

Последний раз редактировалось Uragan66, 27-06-2019 в 22:04.


Отправлено: 21:57, 27-06-2019 | #12


Старожил


Сообщения: 216
Благодарности: 15

Профиль | Отправить PM | Цитировать


Составил такой RegExp:
Код: Выделить весь код
^(#EXTINF.*[^\n\r]+\r?\nhttps?:\/\/[^\n\r]+\r?\n?|#EXTINF.*[^\n\r]+\r?\nrtmp:\/\/[^\n\r]+\r?\n?|#EXTINF.*[^\n\r]+\r?\nmms:\/\/[^\n\r]+\r?\n?|#EXTINF.*[^\n\r]+\r?\nrtmpe:\/\/[^\n\r]+\r?\n?|#EXTINF.*[^\n\r]+\r?\nudp:\/\/[^\n\r]+\r?\n?)
Нужные пары строк то ищет, но не получается удалить всё, кроме найденного.

Отправлено: 22:53, 27-06-2019 | #13


Забанен


Сообщения: 793
Благодарности: 260

Профиль | Цитировать


Код: Выделить весь код
for ($i, $arr = 0, (gc input.log); $i -lt $arr.Length;) {
   $a, $b = $arr[$i], $arr[$i + 1] # потенциальная пара
   # критерий относительно которого формируется пара
   if ($a.StartsWith('#') -and $b -match ':\/\/') {
      # выводим пару в окно хоста
      "$a`n$b"
      # переходим на две позиции вперед
      $i += 2
   }
   else {
      # в противном случае переходим к следующему значению
      ++$i
      continue
   }
}
Должно вернуть:
Код: Выделить весь код
#EXTINF:-1 ,Первый канал
http://gorod.tv/s/live/1/46.252.219.59/1561632042766/0.m3u8
#EXTINF:-1 ,Россия 1
http://gorod.tv/s/live/2/46.252.219.59/1561632042766/0.m3u8
#EXTINF:-1 ,Матч ТВ
http://gorod.tv/s/live/3/46.252.219.59/1561632042766/0.m3u8
#EXTINF:-1 ,НТВ
http://gorod.tv/s/live/4/46.252.219.59/1561632042766/0.m3u8
#EXTINF:-1 ,Пятый канал
http://gorod.tv/s/live/5/46.252.219.59/1561632042766/0.m3u8
#EXTINF:-1 ,Россия К
http://gorod.tv/s/live/6/46.252.219.59/1561632042766/0.m3u8
#EXTINF:-1 , Москва 24
http://91.231.219.145:80/tv_moscow_24/video.m3u8
#EXTINF:-1 , Санкт-Петербург
http://91.231.219.145:80/tv_sankt_peterburg/video.m3u8
#EXTINF:-1 ,Discovery
http://hls-v3-spbtv.msk.spbtv.com/for_spb/msk/ipv3/154.m3u8
#EXTINF:-1 ,NASA TV
http://hls-v3-spbtv.msk.spbtv.com/for_spb/msk/ipv3/17.m3u8
#EXTINF:-1 ,Россия 24
http://gorod.tv/s/live/7/46.252.219.59/1561632042766/0.m3u8
#EXTINF:-1 ,Карусель
http://gorod.tv/s/live/8/46.252.219.59/1561632042766/0.m3u8
Это сообщение посчитали полезным следующие участники:

Отправлено: 23:06, 27-06-2019 | #14


Старожил


Сообщения: 216
Благодарности: 15

Профиль | Отправить PM | Цитировать


greg zakharov, спасибо большое!
Но у меня почему-то не получается запустить скрипт, выдаёт ошибку компиляции:

Отправлено: 07:58, 28-06-2019 | #15


Забанен


Сообщения: 793
Благодарности: 260

Профиль | Цитировать


Uragan66, ничего удивительного: вы пытаетесь запустить сценарий pwsh как WSH, - последнему ничего не известно о синтаксисе PowerShell.
Это сообщение посчитали полезным следующие участники:

Отправлено: 08:59, 28-06-2019 | #16


Старожил


Сообщения: 216
Благодарности: 15

Профиль | Отправить PM | Цитировать


greg zakharov, извините, думал, что скрипт нужно запускать как js.
Теперь разобрался... Большая благодарность за скрипт!

Последний раз редактировалось Uragan66, 28-06-2019 в 11:00.


Отправлено: 09:07, 28-06-2019 | #17


Старожил


Сообщения: 216
Благодарности: 15

Профиль | Отправить PM | Цитировать


Немного подправил скрипт под свою задачу:
Код: Выделить весь код
@(for($i, $arr = 0, (gc .\*.m3u -Encoding utf8); $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 | Out-File .\out.m3u -Encoding utf8
Отрабатывает отлично...
Ещё раз большое спасибо всем за помощь!

Отправлено: 11:34, 28-06-2019 | #18


Старожил


Сообщения: 216
Благодарности: 15

Профиль | Отправить PM | Цитировать


Здравствуйте!
Использую, подсказанный ув. greg zakharov, скрипт:
Код: Выделить весь код
@(for($i, $arr = 0, (gc .\*.m3u -Encoding utf8); $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 | Out-File .\out.m3u -Encoding utf8
Скрипт работает отлично, ещё раз большое спасибо!
Но бывает возникает необходимость пускать на вход не один файл, а несколько.
Подскажите, пожалуйста, можно ли для обработки скриптом прописать не один файл, а папку с файлами одного расширения ?
Буду премного благодарен за ответы и подсказки.

Отправлено: 15:30, 24-08-2019 | #19


Аватара для DJ Mogarych

fascinating rhythm


Moderator


Сообщения: 6491
Благодарности: 1465

Профиль | Отправить PM | Цитировать


Цитата Uragan66:
можно ли для обработки скриптом прописать не один файл, а папку с файлами одного расширения ? »
Код: Выделить весь код
gc C:\temp\*.txt

-------
Powershell 7.x | Powershell 5.1 | ffmpeg (docs)


Последний раз редактировалось DJ Mogarych, 24-08-2019 в 16:42.

Это сообщение посчитали полезным следующие участники:

Отправлено: 15:58, 24-08-2019 | #20



Компьютерный форум OSzone.net » Программирование, базы данных и автоматизация действий » Скриптовые языки администрирования Windows » Любой язык - [решено] Удаление дубликатов строк из текстового файла со сравнением по две строки

Участник сейчас на форуме Участник сейчас на форуме Участник вне форума Участник вне форума Автор темы Автор темы Шапка темы Сообщение прикреплено

Похожие темы
Название темы Автор Информация о форуме Ответов Последнее сообщение
Любой язык - Удаление из txt файлов не нужных строк и дубликатов строк. voler Скриптовые языки администрирования Windows 1 26-02-2018 14:10
Delphi - Обработчик строк из текстового файла pageYK@fb Программирование и базы данных 18 11-08-2016 13:40
CMD/BAT - [решено] Удаление строки из текстового файла Elven Скриптовые языки администрирования Windows 2 29-11-2013 17:44
CMD/BAT - Поиск и копирование нескольких строк из текстового файла. valen Скриптовые языки администрирования Windows 0 07-11-2011 17:27
CMD/BAT - [решено] Перенос и удаление строк из текстового файла sk8ter Скриптовые языки администрирования Windows 15 03-10-2010 19:35




 
Переход