uscr 02.07.2011 19:29
Есть вопрос! — [РЕШЕНО] Обработать несколько миллионов файлов.
Здравствуйте. Есть каталог, в котором лежат около 5 миллионов файлов. Все они имеют название по шаблону: <�одинаковые для всех буквы>_<�дата создания><�разные цифры>. Нужно эти файлы скормить скрипту. Скрипт может есть файлы, которые лежат в определённом каталоге. Т.Е. задача сводится к тому, что бы перемещать файлы порциями (например, по 1000 штук) в другой каталог. Проблема в том, что при попытке как-либо взаимодействовать с этими файлами - всё виснет (что не удивительно). Что можно придумать?UPD
Спасибо всем за предложеные способы. Всё попробую чуть позже. Сейчас к машине нет доступа.
Решение:
ls получает список ВСЕХ файлов не потому, что он тупой и вредный, а потому, что он хочет их отсортировать перед выводом. У команды ls есть ключ -U (unsorted). Так что ls -U | head -1000 отрабатывает (всего) за три секунды.
transserg 02.07.2011 20:08 #
+ 1 -
ну если на С написать простую прожку которая будет дергать по 1000 файлов (или чуть больше) и отдавать скрипту. других вариантов пока не пришло в голову
Я не знаю С. Пробовал в питоне использовать os.walk() - это функция - итератор, написаная как раз на С. Но тоже подвисло всё.
Ну... Он ведь итератор. Кажется, в том и фишечка, что не нужен ему весь список. Нет?
думаю зависит от реализации.
вот есть range() который отдает сразу все объекты, если их много, то занимается много памяти.
есть xrange() который отдает объекты последовательно
вот есть range() который отдает сразу все объекты, если их много, то занимается много памяти.
есть xrange() который отдает объекты последовательно
Хехе. Это попробовал в первую очередь. Помню фишечку с разрывом пайпа, но тут не сработало. Видимо, ls работает не "налету", а сначала всё таки получает список.
сделай ls | wc -l. я пробовал вышеуказанный трюк с каталогом в котором было 760 тысяч файлов. etx4 дефолтные настройки, отработало ≈30 сек.
можно попробовать с find /path/ -type f -name 'шаблон' -print | head -n1000 find печатает на вывод файлеки по мере нахождения.
можно попробовать с find /path/ -type f -name 'шаблон' -print | head -n1000 find печатает на вывод файлеки по мере нахождения.
ls | wc -l
Всякие ухищрения с find -всё это зависает :(
Может глюк самой ФС?
Всякие ухищрения с find -всё это зависает :(
Может глюк самой ФС?
Похоже на то. Как я ниже написал, find читает файлы последовательно и количество файлов ему всё равно должно быть.
Интересно, кстати, какой размер файла каталога.
ls -ld
Интересно, кстати, какой размер файла каталога.
ls -ld
Похоже всё дело в реализации пайпов. Места у меня хватило только на 3 178 311 файлов. При использовании пайпа например в ls | head -n1000 оно хавает полгига и на эту операцию уходит 1 минута. (ext4, старый ide-hdd, 7200 rpm, 8Mb cache; каталог /tmp/site файлы по шаблону abcd_номерфайла, содержимое файлов - их номер). Пока проверяю что и как лучше сделать обычный ls в каталоге съел пока 40 мегов, продолжает медленно пожирать память, работает уже больше 2 минут, результата всё ещё нет )
Я, к сожалению, не знаю, чсколько там на самом деле файлов. Миллионы - это предположение. Система такая: ваершарк дампит трафик, нечто режет дамп на файлы. Один файл - один пакет. Эти файлы потом обрабатывает скрипт. Внезапно, скрипт оказался нерабочим, но замечено это было только через месяц. И весь месяц трафик дампился и резался...
Так что файлов там может оказаться и больше сотни миллионов.
Так что файлов там может оказаться и больше сотни миллионов.
Могу предложить вот такую штуку (парсер лох, поэтому на пастбине). Работает молниеносно, памяти не жрёт, выдаёт по 1001 файлу или всё, что есть, если их меньше ☺
А если выбирать по маске <�буквы>_<�дата>*, повиснет или нет?
Если нет, то начиная от сегодняшней даты можно пробежаться циклом в прошлое, откручивая на каждом шаге один день.
Если нет, то начиная от сегодняшней даты можно пробежаться циклом в прошлое, откручивая на каждом шаге один день.
приведи примеры как ты с ними взаимодействуешь и на каком моменте все виснет
Так ведь xargs как раз для этого?
Скрипт и передать, который будет обрабатывать файлы. А xargs будет скармливать скрипту найденные файлы маленькими порциями.
Хм. Судя по минусу, я спросил очень глупу вещь. Но разве xargs не работает в пайпе? Типа: find blablabla|xargs blablabla?
Компенсировал минус на 0. :)
Да, правильно -- xargs так и работает, но find совершенно не должен зависать. Очень странно, что find зависает, потому что find не читает все файлы скопом -- видимо, всё-таки глюк файловой системы. Я бы сделал fsck, вдруг с катологом что-то.
Да, правильно -- xargs так и работает, но find совершенно не должен зависать. Очень странно, что find зависает, потому что find не читает все файлы скопом -- видимо, всё-таки глюк файловой системы. Я бы сделал fsck, вдруг с катологом что-то.
http://pastebin.com/9nCAWNqk
как использовать, думаю, сам догадаешься
как использовать, думаю, сам догадаешься
Попробуй, как вариант, воспользоваться утилитой dd. Она вроде отличается от прочих тем что обращается именно к {байтам,блокам,секторам} и т.п. в отличии стандартных утилит, которые вроде открывают файловые потоки.
Если знаешь точное имя какого-нибудь файла попробуй с помощью dd сделать дубликат по абсолютному пути. Если выйдет, но с регулярными выражениями не выйдет (что вполне возможно), значит придётся подстановкой создавать строковую переменную и подставлять в dd или будем думать как решить проблему.
Если знаешь точное имя какого-нибудь файла попробуй с помощью dd сделать дубликат по абсолютному пути. Если выйдет, но с регулярными выражениями не выйдет (что вполне возможно), значит придётся подстановкой создавать строковую переменную и подставлять в dd или будем думать как решить проблему.