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

Компьютерный форум 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

 

Ветеран


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

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


Цитата Uragan66:
Например: »
Так:
Код: Выделить весь код
$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:0, 1+1
http://193.106.211.2:1234/udp/225.1.1.103:4001
#EXTINF:0, 2+2
http://193.106.211.2:1234/udp/225.1.1.115:4001
#EXTINF:0, 5 канал
http://193.106.211.2:1234/udp/225.1.1.105:4001
#EXTINF:0, ICTV
http://193.106.211.2:1234/udp/225.1.1.104:4001
#EXTINF:0, канал «Киев»
http://193.106.211.2:1234/udp/225.1.1.114: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.112: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.106: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.111:4001
#EXTINF:0, ТРК «Киев»
http://193.106.211.2:1234/udp/225.1.1.114:4001
#EXTINF:0, ТРК «Украина»
http://190.106.210.2:1234/udp/225.1.1.107:4001
#EXTINF:0, ТРК «Украина»
http://193.106.211.2:1234/udp/225.1.1.107:4001
?
Это сообщение посчитали полезным следующие участники:

Отправлено: 04:07, 27-06-2019 | #2



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

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


Старожил


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

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


Iska, спасибо! Да, выходной файл должен быть именно таким. Но у меня Ваш код почему-то не срабатывает. Входной файл остаётся без изменений.


P.S. Мои извинения, всё работает, это я с запуском затупил. Сейчас запуская скрипт батником:
Код: Выделить весь код
@echo off
Powershell -File ./sortes.ps1 >> test.txt
файл test.txt получается без дублей.
Но есть некоторые нюансы. Скрипт ps1 нормально читает файлы только в кодировке ANSI, а в выходном файле кодировка OEM866 (это говорит AkelPad, а Notepad++ определяет как ANSI).
Можно как-то переделать на UTF-8 ?
А то на выходе, если в входном файле есть кавычки типа:
Код: Выделить весь код
ТРК «Киев»
получается:
Код: Выделить весь код
ТРК <Киев>
Спасибо!

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


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


Забанен


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

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


Iska, (ради спортивного интереса) задачу можно решить короче через (MINGW|Cygwin|WSL):
Скрытый текст
Код: Выделить весь код
sed 'N;s/\n/ - /' input.log | sort | sed 'N;/^\(.*\)\n\1$/!P;D' | sed 's/ - /\n/g'

Можно, правда, еще короче:
Скрытый текст
Код: Выделить весь код
sed 'N;s/\n/ - /' input.log | sort | uniq | sed 's/ - /\n/g'

Если лог большой, лучше через parallel, а еще лучше и вовсе на чистом perl (также однострочник). Но это дело вкуса.
Это сообщение посчитали полезным следующие участники:

Отправлено: 09:02, 27-06-2019 | #4


Аватара для YuS_2

Crazy


Contributor


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

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


Цитата greg zakharov:
(ради спортивного интереса) задачу можно решить короче »
Код: Выделить весь код
gc test.txt -r 2|%{"$($_[0])`n$($_[1])"}|sort -uni

-------
scio me nihil scire. Ѫ

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

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


Забанен


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

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


YuS_2, ReadCount ведь уже установлен в пару, зачем там цикл? Просто select -u:
Код: Выделить весь код
gc input.log -r 2 | select -u
или, если сортировка принципиальна:
Код: Выделить весь код
gc input.log -r 2 | sort | select -u
pwsh прекрасно поймет, что от него хотят.
Это сообщение посчитали полезным следующие участники:

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


Старожил


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

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


Ребята, спасибо всем !
Но вопрос с кодировкой так и остался.
Входной файл/файлы в utf-8 и после скрипта, предложенного ув. Iska, с русскими символами на выходе беда, крякозябры выходят.
Сортировка в тексте не обязательна, главное удаление дублей парных строк.
С остальными скриптами не совсем разобрался, как их запускать.

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


Забанен


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

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


Код: Выделить весь код
gc input.log -encoding utf8 ...
При выводе в файл оператор перенаправления (>) "пишет" в utf8 (если ничего не путаю), но лучше использовать командлет Out-File для последующей записи в файл (в нем можно указать конечную кодировку).
Цитата Uragan66:
С остальными скриптами не совсем разобрался, как их запускать.
Это - однострочники (для дзенствующих ), выполняются прямо в хосте pwsh.

Последний раз редактировалось greg zakharov, 27-06-2019 в 14:20.

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

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


Аватара для YuS_2

Crazy


Contributor


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

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


Цитата greg zakharov:
ReadCount ведь уже установлен в пару, зачем там цикл? »
не помню, что-то там у меня сразу не пошло, вроде бы, строки перемешались в каком-то варианте, поэтому в цикл засунул, чтобы наверняка
Цитата greg zakharov:
если сортировка принципиальна: »
у сорт, кстати, тоже есть параметр -Unique, т.е. достаточно:
Код: Выделить весь код
gc test.txt -r 2|sort -u

-------
scio me nihil scire. Ѫ


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

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

Отправлено: 15:47, 27-06-2019 | #9


Старожил


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

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


С кодировкой и выводом всё получилось.
Огромная благодарность всем за помощь!

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



Компьютерный форум 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




 
Переход