Como gerenciar uma quantidade enorme de arquivos no shell?

9

$ ls ./dir_with_huge_amount_of_files/errors/

Suponha que um diretório esteja cheio de imagens com timestamps unix, quero dizer muito medido em muitos GBs ou até mais. Comandos shell como ls receberão avisos de estilo de estouro porque eles não foram projetados para funcionar com milhões (ou mais) de imagens. Como posso gerenciar uma quantidade tão grande de arquivos? Se, por exemplo, eu quiser encontrar a imagem no meio (de acordo com o registro de data e hora no nome e na hora da criação), existe algum sistema de arquivos que ofereça um recurso de pesquisa embutido? Quais comandos você usaria? Eu tentei o confortável ls e find com sinalizadores necessários, mas eles eram muito lentos ou geravam avisos, então estou pensando que ou eu preciso de um melhor sistema de arquivos ou banco de dados ou algo parecido para pré-indexar as imagens. Eu basicamente preciso de um array para o qual os inodes das fotos devem ser colocados em ordem cronológica. Como fazer isso? Mais tarde, metadados com unix-timestamps poderiam ser adicionados.

[Atualização]

Existe uma falha séria nas respostas atuais, as pessoas apenas postam respostas sem testes empíricos. Se eles tivessem testado suas sugestões, provavelmente fracassariam. Por isso, criei uma ferramenta de linha de comando para criar a caixa de proteção para criar a enorme quantidade de arquivos e testar suas sugestões com uma quantidade de arquivos de 1e7. Pode levar muito tempo para gerar os arquivos, então seja paciente. Se alguém souber uma maneira mais rápida de fazer isso, edite o código. Digite python code.py --help para obter ajuda. Divirta-se!

Exemplo de uso para criar muitos arquivos direcionados

$ ls ./data2
ls: ./data2: No such file or directory
$ python testFill.py -n 3 -d 7                                                 
$ tree data2/                                                                  
data2/
|-- 0
|   |-- 1302407302636973
|   |-- 1302407302638022
|   '-- 1302407302638829
|-- 1
|   |-- 1302407302639604
|   |-- 1302407302641652
|   '-- 1302407302642399
|-- 2
|   |-- 1302407302643158
|   |-- 1302407302645223
|   '-- 1302407302646026
|-- 3
|   |-- 1302407302646837
|   |-- 1302407302649110
|   '-- 1302407302649944
|-- 4
|   |-- 1302407302650771
|   |-- 1302407302652921
|   '-- 1302407302653685
|-- 5
|   |-- 1302407302654423
|   |-- 1302407302656352
|   '-- 1302407302656992
'-- 6
    |-- 1302407302657652
    |-- 1302407302659543
    '-- 1302407302660156

7 directories, 21 files

Código testFill.py

# Author: hhh
# License: ISC license

import os, math, time, optparse, sys

def createHugeAmountOfFiles(fileAmount, dirAmount):
   counter = 0
   DENSITY = 1e7
   dir = "./data/"

   do = dir+str(counter)+"/"
   while (os.path.exists(do)):
      counter = counter+1
      do = dir+str(counter)+"/"

   os.mkdir(do)

   for d in range(int(dirAmount)):
      for f in range(int(fileAmount)):
         timeIt = int(time.time()*1e6)
         if (not os.path.exists(do)):
            os.mkdir(do)

         if (timeIt % DENSITY == 0):
            counter = counter+1
            do = dir+str(counter)+"/"

            if (not os.path.exists(do)):
               os.mkdir(do)


         do = dir+str(counter)+"/"
         if(not os.path.exists(do)):
            os.mkdir(do)

         f = open(do+str(timeIt), 'w')
         f.write("Automatically created file to test Huge amount of files.")
         f.close()
      counter = counter +1


def ls(dir):
   for root, dirs, files in os.walk("./data/"+dir):
      print(files)

def rm(dir):
   for root, dirs, files in os.walk("./data/"+dir):
      for f in files:
         os.remove("./data/"+dir+"/"+f)


def parseCli():
   parser = optparse.OptionParser()
   parser.add_option("-f", "--file", dest="filename",
                     help="Location to remove files only in ./Data.", metavar="FILE")
   parser.add_option("-n", "--number", dest="number",
                     help="Number of files to generate", metavar="NUMBER")
   parser.add_option("-r", "--remove", dest="remove",
                     help="Data -dir content to remove", metavar="NUMBER")
   parser.add_option("-d", "--dir", dest="dir",
                     help="Amount of dirs to generate", metavar="NUMBER")
   parser.add_option("-q", "--quiet",
                     action="store_false", dest="verbose", default=True,
                     help="don't print status messages to stdout")

   return parser.parse_args()

def main():
   (options, args) = parseCli()

   if (options.filename):
      ls(options.filename)
   if (options.number and options.dir):
      createHugeAmountOfFiles(options.number, options.dir)
   if (options.remove):
      rm(options.remove)


main()
    
por Kevin Bowen 25.03.2011 / 01:11

2 respostas

4

Tente um shell diferente. Eu recomendaria tentar zsh por exemplo, e ver se ele permite mais parâmetros.

Se eu entendi corretamente, parte do nome do arquivo, é um timestamp do UNIX. Pode ser aconselhável dividir os arquivos em pastas. Se o formato de data / hora for um número de época do UNIX, coloque blocos de frações desse número, digamos 10000, em uma pasta separada.

Se um timestamp da ISO 8601 fizer parte do nome do arquivo, basta dividir por ano, mês ou dia.

    
por 25.03.2011 / 06:15
1

Será que locate (e, é claro, updatedb ) ajudará você?

    
por 25.03.2011 / 04:57