Ваша задача звучит так, как будто вы хотите попробовать watch
: она может периодически запускать команду и показывать ее вывод. Используя его -g (--chgexit)
(выход при изменении выхода), вы можете попытаться достичь желаемого. Я имею в виду следующее (не проверено):
#!/bin/bash
MON_DIR="/home/lab"
if [ -d $MON_DIR ] ; then
echo "Directory exists."
while true
do
watch -n 2 -g "ls ${MON_DIR}" > /dev/null
echo "Content has changed."
done
else
echo "Directory does not exists." > /dev/stderr
exit $? > /dev/stderr
fi
Я подавляю вывод watch
здесь, чтобы убедиться, что вы сможете увидеть сообщение. Вы также можете заменить бесконечный цикл (while true
) чем-то, что может быть лучше прервано: Ctrl + C прервет watch
и цикл перезапустит его. Таким образом, вам придется дважды нажать Ctr + C за короткий промежуток времени.
Если вам нужно только 200 из 50 миллионов строк, то чтение всего этого в память - пустая трата времени. Я бы отсортировал список ключей поиска и затем применил бинарный поиск к файлу, используя seek () или что-то подобное. Таким образом, вы не прочитали бы весь файл в память, что, я думаю, должно ускорить процесс.
Непонятно, что такое «список [указатель]». Однако учтите это.
from collections import defaultdict
keyValues= defaultdict(list)
targetKeys= # some list of keys
for line in fin:
key, value = map( int, line.split())
if key in targetKeys:
keyValues[key].append( value )
Небольшая оптимизация ответа С.Лоттса:
from collections import defaultdict
keyValues= defaultdict(list)
targetKeys= # some list of keys as strings
for line in fin:
key, value = line.split()
if key in targetKeys:
keyValues[key].append( value )
Поскольку мы используем словарь, а не список, ключи не должны быть числами. Это сохраняет операцию map () и преобразование строки в целое число для каждой строки. Если вы хотите, чтобы ключи были числами, выполните преобразование в конце, когда вам нужно сделать это только один раз для каждого ключа, а не для каждой из 50 миллионов строк.
Я бы использовал отображение памяти: http://docs.python.org/library/mmap. HTML .
Таким образом, вы можете использовать файл так, как будто он хранится в памяти, но ОС решает, какие страницы на самом деле следует прочитать из файла.
Вот рекурсивный двоичный поиск по текстовому файлу
import os, stat
class IntegerKeyTextFile(object):
def __init__(self, filename):
self.filename = filename
self.f = open(self.filename, 'r')
self.getStatinfo()
def getStatinfo(self):
self.statinfo = os.stat(self.filename)
self.size = self.statinfo[stat.ST_SIZE]
def parse(self, line):
key, value = line.split()
k = int(key)
v = int(value)
return (k,v)
def __getitem__(self, key):
return self.findKey(key)
def findKey(self, keyToFind, startpoint=0, endpoint=None):
"Recursively search a text file"
if endpoint is None:
endpoint = self.size
currentpoint = (startpoint + endpoint) // 2
while True:
self.f.seek(currentpoint)
if currentpoint <> 0:
# may not start at a line break! Discard.
baddata = self.f.readline()
linestart = self.f.tell()
keyatpoint = self.f.readline()
if not keyatpoint:
# read returned empty - end of file
raise KeyError('key %d not found'%(keyToFind,))
k,v = self.parse(keyatpoint)
if k == keyToFind:
print 'key found at ', linestart, ' with value ', v
return v
if endpoint == startpoint:
raise KeyError('key %d not found'%(keyToFind,))
if k > keyToFind:
return self.findKey(keyToFind, startpoint, currentpoint)
else:
return self.findKey(keyToFind, currentpoint, endpoint)
Пример текстового файла, созданного в jEdit, похоже, работает:
>>> i = integertext.IntegerKeyTextFile('c:\\sampledata.txt')
>>> i[1]
key found at 0 with value 345
345
Это определенно можно улучшить, кэшируя найденные ключи и используя кеш для определения будущих начальных точек поиска.
Одной из возможных оптимизаций является небольшая буферизация с использованием опции sizehint
в file.readlines (..) . Это позволяет загружать в память несколько строк общим объемом примерно sizehint
байтов.
Если у вас есть какой-либо контроль над форматом файла, ответы «сортировка и двоичный поиск» верны. Суть в том, что это работает только с записями фиксированного размера и смещения (ну, я должен сказать, что это легко работает только с записями фиксированной длины).
С записями фиксированной длины вы можете легко искать () вокруг отсортированного файла в найди свои ключи.
Вам необходимо реализовать бинарный поиск с использованием seek ()