2017-02-19 14 views
1

У меня есть отрезок моего сценария, который будет создавать список файлов для сканирования с помощью ключевых слов ..Список имен файлов изменен в течение 1 недели

Проблема заключается в том, что файлы журнала в совокупности около 11GB. Когда я использую grep в оболочке для поиска по ним, это занимает около 4 или 5 минут. Когда я делаю это с помощью своего сценария python, он просто зависает на сервере в той мере, в какой мне нужно перезагрузить его.

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

У меня это до сих пор:

logs = [log for log in glob('/var/opt/cray/log/p0-current/*') if not os.path.isdir(log)] 

Я предполагаю, что мне нужно будет добавить что-то до этого сначала отфильтровать неправильные файлы?

Я играл с os.path.getmtime в этом формате:

logs = [log for log in glob('/var/opt/cray/log/p0-current/*') if not os.path.isdir(log)] 

for log in logs: 
    mtime = os.path.getmtime(log) 
    if mtime < "604800": 
     do-stuff (create a new list? Or update logs?) 

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

+0

Если вы хотите элегантное использование 'man find'. В противном случае попробуйте создать пример [Минимальный, Полный и Подтверждаемый] (http://stackoverflow.com/help/mcve). Это облегчает нам помощь. –

+0

Не уверен, что вы имеете в виду, я не знал, что 'find()' это вещь в Python. Я изучаю. Я думал, что мое объяснение моих требований было минимальным, полным и поддающимся проверке. Глядя на добавление дальнейшей подгонки к условиям, которые строят мой список. Таким образом, в настоящее время список 'logs' содержит огромное количество имен файлов, но я хотел бы обрезать это до файлов, которые имеют модифицированное время менее 604800 секунд (1 неделя), я помещаю его в считанные секунды, потому что, когда я использую' os.path.getmtime (log) ', а затем распечатать результаты, я получаю огромное количество. Я посмотрел 'os.path.getmtime()' и нашел, что результаты находятся в сексе – jonnybinthemix

+0

@StephenRauch - Можно ли использовать что-то похожее на обычную оболочку? 'find/path/to/logs -type f -mtime -7' - Это было бы намного чище. За 2 недели я изучал Python .. все кажется намного более длинным, чем обычный скрипт оболочки. Я уверен, что это мое отсутствие понимания, но я изо всех сил пытаюсь найти преимущества Python над Bash на данный момент. – jonnybinthemix

ответ

3

В зависимости от того, сколько имен файлов и сколько памяти (512 МБ VPS?), Возможно, у вас закончилась нехватка памяти, создавая два списка всех имен файлов (один из glob и один из вашего списка). Не обязательно но это все, что мне нужно.

Попробуйте переключиться на iglob (который использует os.scandir под капотом и возвращает итератор) и с использованием выражения генератора и посмотрите, поможет ли это.

Кроме того, getmtime получает время, а не интервал отныне.

import os 
import glob 
import time 

week_ago = time.time() - 7 * 24 * 60 * 60 
log_files = (
    x for x in glob.iglob('/var/opt/cray/log/p0-current/*') 
    if not os.path.isdir(x) 
    and os.path.getmtime(x) > week_ago 
) 
for filename in log_files: 
    pass # do something 
+0

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

+0

Это работает очень хорошо!Я тестировал наряду с 'find/var/opt/cray/log/p0-current -mtime -7 -maxdepth 1', и выше ответили на тот же список, поэтому он работает хорошо. Я не получаю 'и os.path.getmtime (x)> week_ago' В моей голове это говорит, что mtime больше 1 недели? Или я чего-то не хватает? – jonnybinthemix

+0

mtime вот когда, не так давно, так> для после –