Удаление дубликатов в больших файлах, проблема...

  • Автор темы Автор темы jeka!
  • Дата начала Дата начала

jeka!

Просто Member
Удаление дубликатов в больших файлах, проблема...

Написал скрипт который открывает файл и удаляет все дублирующиеся записи, потом сохраняет его под новым именем.
На локалке всё прекрасно работает, файлы размером 6 мегов нормально обрабатываются, поставил скрипт на хостинг sweb.ru и там нифига он не работает.
В общем файлы до 1 мега обрабатываются, всё что больше, нет, скрипт умерает и браузер пишет "500 ошибку".

Файлы имеют такой вид:
127.0.0.1
127.0.0.2
127.0.0.3
127.0.0.4
и т.д.

Скрипт:
PHP:
if (file_exists('ip.txt')) {
	$fp=fopen('ip.txt','r');
	$fr=fread($fp,filesize('ip.txt'));
	fclose($fp);
	$arr=explode('\n',$fr);
	foreach ($arr as $val) {
		if ($val=="" || $val=='\n') continue;
		$val=str_replace('\n','',$val);
		$new[$val]=null;
	}
	$fp=fopen('ipnew.txt','w');
	foreach ($new as $key => $val) {
		fputs($fp,$key.'\n');
	}
	fclose($fp);
}

Помогите решить проблему средствами PHP.
Или если не возможно, тогда может есть какая нибудь линуксовая команда, которая удаляет дубликаты из файлов.
 
Может быть рациональнее будет сделать что бы при добавлении нового IP была проверка на возможное существования такого IP в файле!?
 
Если скрипт дохнет сразу, возможно, он упирается в лимит по используемой памяти. Попробуй обрабатывать файл по частям.

Если скрипт зависает и долго не отвечает, возможно, он упирается в лимит по времени исполнения. Попробуй поиграться с функцией set_time_limit().
 
твой скрипт пишется в 3 строчки
[m]file[/m] + [m]array_unique[/m]
но ограничение памяти, действительно может сосздавать проблемы.
 
while(!feof($fpIn))
{
$s=fgets($fpIn)
if(!isset($keys[$s])) fwrite($fpOut,$s)
$keys[$s]=1;
}

man uniq
 
>Через БД все было бы гораздо проще
а если подумать ? или попробовать потестировать ?
 
Может быть рациональнее будет сделать что бы при добавлении нового IP была проверка на возможное существования такого IP в файле!?
Это делать не рационально в плане используемых ресурсов компа.
Если скрипт дохнет сразу, возможно, он упирается в лимит по используемой памяти. Попробуй обрабатывать файл по частям.
Он я думаю именно в это и упирается.
твой скрипт пишется в 3 строчки
file + array_unique
но ограничение памяти, действительно может сосздавать проблемы.
Да, так конечно можно, но с файлами до 5 мегов (точно не помню).
Дело в том, что file() вобще не работает с файлами большего размера, и тут хоть 500 мегов лимит памяти выставляй, толку никакого. Я эту тему на форуме подымал ещё год назад.
А у меня списки проксей могут быть и по 20 метров.

while(!feof($fpIn))
{
$s=fgets($fpIn)
if(!isset($keys[$s])) fwrite($fpOut,$s)
$keys[$s]=1;
}
Практически тоже самое, только скрипт умрёт не сразу, а немного позднее когда переменная $keys[$s] заполнится до лимита памяти.
Хотя с другой стороны, если её размер проверять, и освобождать если заполнится, то возможно так можно и сделать, или в 2 этапа пройти сортировку.
Хотя наверное мала вероятность в данной ситуации, что стока наберётся оригиналов.
Надо в общем потестировать...
Через БД все было бы гораздо проще
Ну вобще то я так на край и хотел делать, просто создать временную таблицу, записать туда построчно в униальную колонку все строки и потом выбрать соответственно.
Но это не пхп решение...

Меня просто удивляет такой факт, у меня на локалке стоит denver с настройками по умолчанию, я свободно читаю файлы размером в 700 мегов, тобишь выводил сумму MD5 для всоего архива фильмов.
А на хостинге даже 5 меговые файлы не загружаются, от чего это зависит, не понятно...
 
Задача решается сортировкой исходного файла. После этого нахождение дубликатов превращается в элементарную задачу. Загрузку памяти можно сократить до десятков байт.

Сортировку исходного файла можно сделать и у себя на машине перед отправкой его на сервер. Либо найти где-нибудь готовую программу, либо самому написать. Сортировка по возрастанию номеров не важна, достаточно самой примитивной алфавитной.

P. S. Google нашёл более простое решение. :-)

http://www.die.net/doc/linux/man/man1/sort.1.html

Там есть такой параметр, называется "q". Вроде бы, должен отфильтровывать повторяющиеся строки. Так что вопрос лишь в запуске команды через shell_exec.
 
Lav
тогда почему бы у себя на машине сразу и не убить дубликаты ?

-~{}~ 30.03.04 10:42:

только что попробовал прочитать файл 26М, все нормально.
php4.3.4 apache 1.3.29
 
Demiurg
А это, кстати, вполне может оказаться самым простым решением. Но в начальной постановке задачи были слова "средствами PHP" и "линуксовая команда", так что приходится выкручиваться. ;-)
 
Спасибо за man sort, http://www.die.net/doc/linux/man/man1/sort.1.html
думаю теперь разберусь...
Понятное дело что если отсортировать, то всё проще будет, тогда можно просто файлы на край поделить, скажем по 1 мегу и рекурсивно обработать..
 
Originally posted by jeka!
Спасибо за man sort, http://www.die.net/doc/linux/man/man1/sort.1.html
думаю теперь разберусь...
Понятное дело что если отсортировать, то всё проще будет, тогда можно просто файлы на край поделить, скажем по 1 мегу и рекурсивно обработать..
jeka, смотри ключ "-u"
 
Да, всё сделал, получилось коротко и быстро...
sort --ignore-leading-blanks --unique --output=./sort.ip.txt ./ip.txt
 
Сверху