Что нового

Поиск резко отличающихся строк в файлах

ВиталийВВ

Новичок
Сообщения
177
Репутация
0
Версия AutoIt: 3.3.x.x

Описание: Существуют 2 файла
Условно старый (old.txt) вида:

6140000081
6140001334
6140001467

И условно новый (new.txt) вида:

6140000081
6140000085
6140001339
6140001469
6140001490

Суть: надо сравнить 2 этих файла построково (вхождение каждой строки 2-го файла в 1-й) и, если строки совпадают (6140000081 = 6140000081) или разница между ними не более 20
(6140000081 = 6140000085), то ничего.
Если же попадается (во втором файле new.txt) строка, которая отличается больше чем на 20 от любой из первого файла (6140001490), то вывести эту строку в отдельный файл.
И так со всеми, которые будут попадать под это условие (отличие больше чем на 20)

Числа в 2 файле (new.txt) всегда больше нежели в первом. т.е. отличие может быть только в одну сторону.
Т.е. если в 1-м фале есть строка:
6140000081
то во втором может быть
6140000083,
но невозможно наличие строки
6140000080


Примечания: Файлы будут большими, в идеале бы добавить в программу Прогресс-бар, показывающий состояние в % отношении до конца обработки.

1. Количество записей во втором файле или равно или больше чем записей в 1 файле
2. Пустая строка есть в самом конце файла. и только 1
3. Кол-во строк в файле - до 1000
 

Yashied

Модератор
Команда форума
Глобальный модератор
Сообщения
5,379
Репутация
2,726
Мне просто интересно, а вы сами пробовали как-то решить эту задачу?
 
Автор
В

ВиталийВВ

Новичок
Сообщения
177
Репутация
0
Пробую, алгоритм примерно понятен, не реализовать вживую его не могу :-( Вот бьюсь.
 

Yashied

Модератор
Команда форума
Глобальный модератор
Сообщения
5,379
Репутация
2,726
Вы должны еще обозначить такие условия:
  • Что делать, если количество записей в первом файле отличается от количества записей во втором (или наоборот).
  • Что делать, если в каком-либо файле присутствуют пустые строки.
  • Насколько большые файлы.
P.S

На самом деле, задачка довольно тривиальная, и решается не выходя за рамки справки.
 

madmasles

Модератор
Глобальный модератор
Сообщения
7,790
Репутация
2,323
ВиталийВВ,
Дайте пример файлов old.txt, new.txt и файла-результата. Желательно не в 5 строк.
 

Yashied

Модератор
Команда форума
Глобальный модератор
Сообщения
5,379
Репутация
2,726
Думаю, что пора закрывать раздел "Стол заказов", а то он очень сильно отупляет народ. :smile:
 
Автор
В

ВиталийВВ

Новичок
Сообщения
177
Репутация
0
Ответы на вопросы поместил в начале темы в примечании. Виды файлов - тут

Файл 1

6140000081
6140001334
6140001467
6140004845
6140004889
6140005490
6140007096
6140009898
6140020131
6140021581
6140026502
6140060799
6140061374
6140065768
6140071987
6140074067
6140100728
6140101343
6140104907
6140121082
6140125410
6140130413
6140131964
6140140606
6140141833
6140144946
6140151367
6140151509
6140154032
6140160003

Файл 2

6140000081
6140001334
6140001467
6140004845
6140004889
6140005490
6140007096
6140009898
6140020131
6140021581
6140026502
6140060799
6140061374
6140065768
6140071987
6140074067
6140100728
6140101343
6140104907
6140121082
6140125410
6140130413
6140131964
6140140609
6140141839
6140144949
6140151369
6140151512
6140154036
6140160009
6140160030

Исходя из этого – новоявленная строка: 6140160030
И выходной файл будет вида:

6140160030
 

veretragna

Как писал, так и работает.
Сообщения
140
Репутация
10
Если я правильно понял, алгоритм может быть примерно следующим.
1) читаем первый файл, параллельно ведем поиск максимального попадающегося значения и пишем его в переменную;
2) просматриваем значения второго файла и проверяем каждое значение по условию "больше ли данное число максимального на 20?", и если есть совпадение - пишем в отдельный файл.

Вот как-то так:

Код:
$OldFile = FileOpen("old.txt", 0)
$NewFile = FileOpen("new.txt", 0)
$DiffFile = FileOpen("diff.txt", 1)

Global $v_Max

While 1
	Local $t = FileReadLine($OldFile)
	If @error then ExitLoop
	If $t = "" then ContinueLoop
	If $v_Max = 0 then $v_Max = $t
	If $t > $v_Max then $v_Max = $t
WEnd
FileClose($OldFile)

$t = 0
While 1
	$t = FileReadLine($NewFile)
	If @error then Exitloop
	If $t = "" then ContinueLoop
	If $t - $v_Max > 20 then FileWriteLine($DiffFile, $t)
WEnd
FileClose($NewFile)
FileClose($DiffFile)


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

Дополнено:
В файл diff.txt, как и положено, записалось значение 6140160030.
 
Автор
В

ВиталийВВ

Новичок
Сообщения
177
Репутация
0
Изначально то природа возникновения задачи:
на работе создаются файлы, они имеют означенную структуру и каждый следующий на 1 больше предыдущего.
Они передаются в центр обработки.
И все бы хорошо, но ИНОГДА работники с какого то перепугу присылают "прошлогодние" файлы. Разглядывать их глазами - неудобно, а вот вычленить таким образом - реально.
За сутки создается не более 10 файлов. Отсюда и число - 20 (с запасом)
Если жепришлют "прошлогодний", то его можно "выделить" по такому признаку.
 

madmasles

Модератор
Глобальный модератор
Сообщения
7,790
Репутация
2,323
ВиталийВВ,
Мой вариант, если я правильно понял задачу.
Код:
#cs ----------------------------------------------------------------------------
	AutoIt Version:		3.3.8.1
	Author:				madmasles
#ce ----------------------------------------------------------------------------
Opt('MustDeclareVars', 1)

Global $sOldFile = @ScriptDir & '\old.txt', $sNewFile = @ScriptDir & '\new.txt', $sResFile = @ScriptDir & '\res.txt', $aOld, $aNew, $sTxt, $hFile

$aOld = StringSplit(StringStripWS(StringStripCR(FileRead($sOldFile)), 3), @LF)
$aNew = StringSplit(StringStripWS(StringStripCR(FileRead($sNewFile)), 3), @LF)
For $i = 1 To $aNew[0]
	Switch $i
		Case 1 To $aOld[0]
			Switch $aNew[$i] - $aOld[$i]
				Case 0 To 20
					ContinueLoop
			EndSwitch
	EndSwitch
	$sTxt &= $aNew[$i] & @CRLF
Next
If $sTxt Then
	$hFile = FileOpen($sResFile, 2)
	FileWrite($hFile, $sTxt)
	FileClose($hFile)
Else
	MsgBox(64, 'Info', 'Нечего писать в файл.')
EndIf
 
Автор
В

ВиталийВВ

Новичок
Сообщения
177
Репутация
0
veretragna сказал(а):
Если я правильно понял, алгоритм может быть примерно следующим.
1) читаем первый файл, параллельно ведем поиск максимального попадающегося значения и пишем его в переменную;
2) просматриваем значения второго файла и проверяем каждое значение по условию "больше ли данное число максимального на 20?", и если есть совпадение - пишем в отдельный файл.

Вот как-то так:

Код:
$OldFile = FileOpen("old.txt", 0)
$NewFile = FileOpen("new.txt", 0)
$DiffFile = FileOpen("diff.txt", 1)

Global $v_Max

While 1
	Local $t = FileReadLine($OldFile)
	If @error then ExitLoop
	If $t = "" then ContinueLoop
	If $v_Max = 0 then $v_Max = $t
	If $t > $v_Max then $v_Max = $t
WEnd
FileClose($OldFile)

$t = 0
While 1
	$t = FileReadLine($NewFile)
	If @error then Exitloop
	If $t = "" then ContinueLoop
	If $t - $v_Max > 20 then FileWriteLine($DiffFile, $t)
WEnd
FileClose($NewFile)
FileClose($DiffFile)


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

Дополнено:
В файл diff.txt, как и положено, записалось значение 6140160030.

Проверил, работает не совсем верно, ибо при:
Файл 1:
6140000081
6140001334
6140001467
и Файл 2:
6140001374

Результатом должен быть:
6140001374

Но результатом является ПУСТОЙ файл.
 

madmasles

Модератор
Глобальный модератор
Сообщения
7,790
Репутация
2,323
ВиталийВВ,
Предупреждение За нарушение общих правил (пункт В.2):
Старайтесь избегать “Over quoting” (преувеличенное цитирование) - цитируйте только необходимую часть сообщения, которая наилучшим образом подчеркнёт суть цитируемого.


С уважением, ваш Глобальный модератор.
 

veretragna

Как писал, так и работает.
Сообщения
140
Репутация
10
ВиталийВВ, 6140001467 больше, чем 6140001374.
Вы же сказали:
Если же попадается (...) строка, которая отличается больше чем на 20 от любой из первого файла (...)
Или есть еще какое-то дополнительное условие для поиска?
 
Автор
В

ВиталийВВ

Новичок
Сообщения
177
Репутация
0
Файл 1:
6140000081
6140001334
6140001467
и Файл 2:
6140001374

6140001374 - отличается больше чем на 20 от 6140001334 и поэтому он должен быть выведен в файл: diff.txt
а он не выводится.
 

veretragna

Как писал, так и работает.
Сообщения
140
Репутация
10
А почему именно 6140001334, а не 6140001467?
Как тогда узнать, какое именно из значений первого файла считать "опорным" для 6140001374 из файла 2? Их ведь могут быть тысячи.
Это какая-то магия?
Поясните свою мысль.
 
Автор
В

ВиталийВВ

Новичок
Сообщения
177
Репутация
0
veretragna сказал(а):
А почему именно 6140001334, а не 6140001467?
Как тогда узнать, какое именно из значений первого файла считать "опорным" для 6140001374 из файла 2? Их ведь могут быть тысячи.
Это какая-то магия?
Поясните свою мысль.

Очень сильно задумался. Пришел к выводу, что опорным может считаться любой "ближний"к означенному.

Т.е. в этом случае 6140001374 дальше чем на 20 отстоит и от 6140001334 и от 6140001467.


Добавлено:
Сообщение автоматически объединено:

Второй вариант решения - тоже не прошел, ибо если:

Файл 1:
6140000081
6140001334
6140001467
6140004845
6140004889

Файл 2:
6140000081
6140001334
6140001374
6140001467

Результатом должно быть:

6140001374 ( он больше чем на 20 отстоит от 6140001334 и 6140001467)

А результата выводится:
6140001374
6140001467
 

veretragna

Как писал, так и работает.
Сообщения
140
Репутация
10
Это в корне меняет дело.
Тогда уточните еще такие моменты.
Насколько большими могут быть файлы? Речь идет о 1-2 Мб или о гигабайтах данных?
Какая закономерность в этих цифрах? Возможен ли такой вариант, что 6140121082 - это "группа 1210, значение равно 82"?
 
Автор
В

ВиталийВВ

Новичок
Сообщения
177
Репутация
0
Размер файла такой, что строк в нем в пределах 1000, строки именно такого формата и такой размерности и такой длины. До копейки.

Возможен ли такой вариант, что 6140121082 - это "группа 1210, значение равно 82"?

Скорее более верно:
6140121082 - 614012 - группа, а в ней 1082 - меняющееся число.
Но беда то в том и есть, что сдуру могу отгрузить файл (появится запись) - 6140120000 (т.е. совсем прошлогодний файл)
 

veretragna

Как писал, так и работает.
Сообщения
140
Репутация
10
Хм... Что же, будем жрать, грустить и думать.
 
Верх