Файлы фильтра в очень большой папке

У меня есть папка с 100k текстовыми файлами. Я хочу поместить файлы с более чем 20 строками в другой папке. Как я делаю это в Python? Я использовал os.listdir, но конечно, нет достаточной памяти для того, чтобы даже загрузить имена файлов в память. Существует ли способ получить, возможно, 100 имен файлов за один раз?

Вот мой код:

import os
import shutil

dir = '/somedir/'

def file_len(fname):
    f = open(fname,'r')
    for i, l in enumerate(f):
        pass
    f.close()
    return i + 1

filenames = os.listdir(dir+'labels/')

i = 0
for filename in filenames:
    flen = file_len(dir+'labels/'+filename)
    print flen
    if flen > 15:
        i = i+1
        shutil.copyfile(dir+'originals/'+filename[:-5], dir+'filteredOrigs/'+filename[:-5])
print i

И вывод:

Traceback (most recent call last):
  File "filterimage.py", line 13, in <module>
    filenames = os.listdir(dir+'labels/')
OSError: [Errno 12] Cannot allocate memory: '/somedir/'

Вот измененный сценарий:

import os
import shutil
import glob

topdir = '/somedir'

def filelen(fname, many):
    f = open(fname,'r')
    for i, l in enumerate(f):
        if i > many:
            f.close()
            return True
    f.close()
    return False

path = os.path.join(topdir, 'labels', '*')
i=0
for filename in glob.iglob(path):
    print filename
    if filelen(filename,5):
        i += 1
print i

это работает над папкой с меньшим количеством файлов, но с большей папкой, все, что это печатает, "0"... Работы над сервером Linux, печать 0 на Mac..., о, хорошо...

6
задан extraeee 4 February 2010 в 19:53
поделиться

5 ответов

Вы можете попробовать использовать GLOCH.GLOB , который возвращает итератор:

topdir = os.path.join('/somedir', 'labels', '*')
for filename in glob.iglob(topdir):
     if filelen(filename) > 15:
          #do stuff

также, пожалуйста, не используйте DIR для имени переменной: вы слежены в.

Еще одним серьезным улучшением, которое вы можете представить, является вашим FileLen функции. Если вы замените его следующим, вы сэкономите много времени. Поверьте мне, То, что у вас сейчас самая медленная альтернатива :

def many_line(fname, many=15):
    for i, line in enumerate(open(fname)):
        if i > many:
            return True
    return False
4
ответ дан 17 December 2019 в 02:28
поделиться

как насчет использования скрипта оболочки? Вы можете выбрать один файл за раз:

for f in `ls`;
loop
if `wc -l f`>20; then
  mv f newfolder
fi
end loop

ppl пожалуйста, исправьте, если я ошибаюсь в любом случае

.
0
ответ дан 17 December 2019 в 02:28
поделиться
import os,shutil
os.chdir("/mydir/")
numlines=20
destination = os.path.join("/destination","dir1")
for file in os.listdir("."):
    if os.path.isfile(file):
        flag=0
        for n,line in enumerate(open(file)):
            if n > numlines: 
                flag=1
                break
        if flag:
            try:
                shutil.move(file,destination) 
            except Exception,e: print e
            else:
                print "%s moved to %s" %(file,destination)
0
ответ дан 17 December 2019 в 02:28
поделиться

В настоящее время принятый ответ просто просто не работает. Эта функция:

def many_line(fname, many=15):
    for i, line in enumerate(line):
        if i > many:
            return True
    return False

имеет две проблемы: во-первых, FNAME ARG не используется, и файл не открывается. Во-вторых, призыв к перечислите (строку) , поскольку линия не определена.

Изменение перечисление . Перечисление (Open (Fname)) исправит его.

0
ответ дан 17 December 2019 в 02:28
поделиться

Пара мыслей. Во-первых, вы можете использовать модуль glob для получения небольших групп файлов. Во-вторых, сортировка по количеству строк займет очень много времени, так как вам придется открывать каждый файл и подсчитывать строки. Если вы можете разбивать файлы по количеству байтов, вы можете избежать открытия файлов с помощью модуля stat . Если критически важно, чтобы разделение происходило на 20 строках, вы можете, по крайней мере, вырезать большие участки файлов, вычислив минимальное количество символов, которое будет иметь 20-строчный файл вашего типа, и не открывать файлы меньшего размера.

2
ответ дан 17 December 2019 в 02:28
поделиться
Другие вопросы по тегам:

Похожие вопросы: