LinuxForum.Fans
Тема

Самый быстрый способ выборки случайного файла из директории

Автор: valet 52 сообщений 10604 просмотров
#299714

"-=Serj=-" написал:
так она уже итак присутствует:
Вот именно, а я хочу чтобы она не присутсвовала :)
Ну я же в любом случае выбираю случайный файл - без этого никак, а раз выбираю то можно как-то использовать результаты этой операции 1 раз.
#299716

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

"valet" написал:
while [ `../rand_file_python|wc -l` -gt 0 ]
do
file=`../rand_file_python`

В моём же варианте цикла - 1 раз. Не?

#299717

"-=Serj=-" написал:
Брр.. Проблема в вашем скрипте в том, что поиск случайного файла выполняется два раза за итерацию:
Да.

"-=Serj=-" написал:
В моём же варианте цикла -  1 раз. Не?
Верно, но у вас появляется дополнительная конструкция - проверка файла на существование - пока не знаю насколько тяжела эта операция, но в любом случае по возможности хотелось бы использовать результат выборки случайного файла - в любом случае это уже есть...
#299719

Но спасибо за идею, привел скрипт к такому виду, мне кажется уже оптимальнее не бывает:

text
#!/bin/bash

cd html_in/

while true do file=`../rand_file_python` if [ -z $file ] ; then break ; fi ../script $file > ../html_out/$file rm -f $file done

cd ../

Единственное все таки проще проверить переменную на существование чем заставлять дергать диск на проверку наличие файла.

П.С. Визуально отрабатываться стало в 2 раза быстрее :)

#299839
"valet" написал:
Кстати как видим я специально для find взял mmin большое, чтобы в критерий попадали заведомо все файлы.

само наличие проверок mmin, как и type сильно тормозят т.к. они вызываются для каждого файла в отдельности...

"valet" написал:
Вот мой скрипт, который обрабатывает файлы (с помощью sed-скрипта script) с большого каталога html_in (в него постоянно другим скриптом докладываются файлы) и складываются в обработанном виде в другой каталог html_out, удаляя в исходном этот файл:

вот расскажи, _НАФИГА_ [прошу прощения за капс] тут нужна выборка _случайного_ файла!?
сколько раз говорить людям, чтобы они полную задачу давали, а не спрашивали, как осуществить идиотское псевдо-решение...

text

#!/bin/bash

list=( $(find . -maxdepth 1 -type f) )

while [ -n "${list[0]}" ]; do for f in "${list[@]}"; do ../script "$f" > "../tst2/$f" rm "$f" done

list=( $(find . -maxdepth 1 -type f) ) done

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

если ну уж очень хочется элемент случайности привнести, то выбирай по 10000 файлов за раз...
а вообще случайность нужна только для криптографии и лотерей...

#299858
"Fat-Zer" написал:
вот расскажи, _НАФИГА_ [прошу прощения за капс] тут нужна выборка _случайного_ файла!?

Тоже об этом подумал:)

#299893

"Fat-Zer" написал:
сколько раз говорить людям, чтобы они полную задачу давали
Да, н ов первом посте как раз и была сформулирована полная задача ))

Fat-Zer, да, ты прав, об этом не подумал. Твое решение самое правильное. Обрабатывать можно пачками.
Спасибо, сделал себе так, все летает.
#299894

"-=Serj=-" написал:
Тоже об этом подумал:)
Да, ребята, вы правы. Собственно случайный выбор задумывался из-за того что каталог постоянно нарастает. А вот про пакетную обработку я как-то не подумал.
#299924
valet написал:
[quote="Fat-Zer"]сколько раз говорить людям, чтобы они полную задачу давали
Да, н ов первом посте как раз и была сформулирована полная задача ))[/quote]
Дык, вы там указали не полную задачу, а своё представление о её решении:

"valet" написал:
скрипт должен постоянно брать случайный файл

Ну и мой вариант

text

#!/usr/bin/env python
#-*- coding: utf-8 -*-

from os import listdir, remove from subprocess import call

while True: files = listdir('.') if len(files) > 0: for f in files: err = call('../script %s > ../tst2/%s' % (f, f), shell = True) if err == 0: remove(f) else: break

#300045

"-=Serj=-" написал:
Ну и мой вариант
попробовал, у меня выбивает ошибку:
text
Traceback (most recent call last):
  File "./obrabotka", line 11, in <module>
    call('script %s > html_out/%s' % f, shell = True)
TypeError: not enough arguments for format string

Так как питона не знаю вообще понятия не имею, что оно от меня хочет.

Кстати тут по скрипту получается что он должен находится в том же каталоге что и файлы, но также нельзя, иначе рано или поздно сам скрипт удалится как один из файлов. То есть тут должен быть переход в каталог обработки, на bash'е это cd html_in для моего случая, как это будет на питоне понятия не имею, может поэтому и ошибка, потому что я привел скрипт к виду:

text
#!/usr/bin/env python
#-*- coding: utf-8 -*-

from os import listdir, remove from subprocess import call

while True: files = listdir('html_in') if len(files) > 0: for f in files: call('script %s > html_out/%s' % f, shell = True) remove(f) else: break

#300046

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

#300047
"valet" написал:
это cd html_in для моего случая, как это будет на питоне понятия не имею
text
#!/usr/bin/env python
#-*- coding: utf-8 -*-

from os import listdir, remove from subprocess import call

while True: files = listdir('./html_in') if len(files) > 0: for f in files: call('./script %s > ./html_out/%s' % f, shell = True) remove(f) else: break

. = текущий каталог
./html_in = каталог html_in лежащий внутри текущего каталога ;)

#300051

Все та же ошибка:

text
Traceback (most recent call last):
  File "./obrabotka", line 11, in <module>
    call('./script %s > ./html_out/%s' % f, shell = True)
TypeError: not enough arguments for format string
#300059
"valet" написал:
Все та же ошибка:

а если не call попробовать

text
#!/usr/bin/env python
#-*- coding: utf-8 -*-

from os import listdir, remove from subprocess import Popen

while True: files = listdir('./html_in') if len(files) > 0: for f in files: cmd = './script %s > ./html_out/%s' cmd_run = Popen(cmd, shell = True) cmd_run.poll() cmd_run.wait() remove(f) else: break

#300068

xxblx, ошибку принципиально не хочешь прочесть?

как-то так:

"valet" написал:
call('script %s > html_out/%s' % (f, f), shell = True)
"valet" написал:
То есть тут должен быть переход в каталог обработки, на bash'е это cd html_in для моего случая, как это будет на питоне понятия не имею, может поэтому и ошибка, потому что я привел скрипт к виду:

os.chdir(); не забудь его импортировать в начале...
а вообще это не важно: скрипт можно вызвать из любого каталога... только нормально путь к sed-скрипту надо прописать или в PATH добавить...

ЗЫ: если хочешь перенести всё включая седовую часть, то лучше на перловку - туда сед на порядок проще портируется...
хотя там и возможны вредные для психики эффекты...
но это на любителя... пользуйся лучше тем, что знаешь...

#300071
"Fat-Zer" написал:
call('script %s > html_out/%s' % (f, f), shell = True)

Ага, извиняюсь... Поправил.

#300074
"Fat-Zer" написал:
xxblx, ошибку принципиально не хочешь прочесть?

Блин, точно. Сам себе поражаюсь - пока носом не тыкнули, не увидел ошибку.
Спасибо за замечание.

Кстати, вопрос, сразу по call и Popen, для подобного скрипта - однофигственно что использовать или call все-таки предпочтительней? Сам я обычно просто всегда делаю
cmd = 'команда'
cmd_run = Popen(cmd, shell = True)
cmd_run.poll()
cmd_run.wait()
Вот интересно стало, может лучше call делать.

#300079

Да не работают, ребята, ваши варианты. Как я понимаю вот эта переменная %s не подставляется:

text
/bin/sed: can't read %s: No such file or directory

Вы хоть сами проверяете что пишите? :)

#300110
"xxblx" написал:
Вот интересно стало, может лучше call делать.

Бизли:


call(args, **parms)
Эта функция выполняет те же действия, что и функция Popen(), за исклю-
чением того, что она просто выполняет команду и возвращает код заверше-
ния (то есть она не возвращает объект класса Popen). Эту функцию удобно
использовать, когда требуется всего лишь выполнить команду и нет необ-
ходимости получать от нее вывод или управлять ею каким-либо способом.
Аргументы имеют тот же смысл, что и в функции Popen().
"valet" написал:
Вы хоть сами проверяете что пишите?

Неа:)

#300132
"valet" написал:
Да не работают, ребята, ваши варианты. Как я понимаю вот эта переменная %s не подставляется:

УМВР.
пользуйся башем или изучай питон...

Войдите или зарегистрируйтесь, чтобы ответить.