쉘에서 대량의 파일을 관리하는 방법?


9

$ ls ./dir_with_huge_amount_of_files/errors/

디렉토리에 유닉스 타임 스탬프가있는 그림으로 가득 차 있다고 가정하면 많은 GB 또는 그 이상으로 측정 된 것을 의미합니다. 셸 명령 ls은 수백만 (또는 그 이상)의 그림으로 작동하도록 설계되지 않았기 때문에 오버플로 스타일 경고를받습니다. 그렇게 많은 양의 파일을 어떻게 관리 할 수 ​​있습니까? 예를 들어, 이름과 생성 시간의 타임 스탬프에 따라 중간에 사진을 찾으려면 내장 검색 기능을 제공하는 파일 시스템이 있습니까? 어떤 명령을 사용 하시겠습니까? 나는 편안 ls하고find필요한 플래그가 있지만 매우 느리거나 경고가 발생했기 때문에 그림을 사전 인덱싱하려면 더 나은 파일 시스템이나 db 또는 이와 유사한 것이 필요하다고 생각합니다. 기본적으로 사진의 inode를 시간 순서대로 배치 해야하는 하나의 배열이 필요합니다. 그렇게하는 방법? 나중에 유닉스 타임 스탬프가있는 메타 데이터를 추가 할 수 있습니다.

[최신 정보]

현재 답변에는 심각한 결함이 있습니다. 사람들은 경험적 테스트없이 일종의 답변을 게시합니다. 그들이 제안을 테스트했다면 실패했을 것입니다. 따라서 샌드 박스를 만들어 엄청난 양의 파일을 만들고 1e7 양의 파일과 같은 제안을 테스트 할 수있는 명령 줄 도구를 만들었습니다. 파일을 생성하는 데 시간이 오래 걸리므로 인내심을 가지십시오. 누군가가 더 빠른 방법을 알고 있다면 코드를 편집하십시오. 유형python code.py --help도움말을 보려면 하십시오. 즐기세요!

많은 dirred 파일을 생성하는 사용 예

$ 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

코드 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()

2
이 스케일에서 데이터 셋을위한 @hhh는 적절하게 인덱스 된 db가 유일한 옵션 일 것입니다
xenoterracide

@ xenoterracide : db조차도 배열과 같은 것을 사용하여 빠른 검색을 구현해야하며 db는 과도한 소리를냅니다. 사진 찍기 소스는 github.com/fsphil/fswebcam 입니다. 아마도 그림을 저장하는 시간에 약간 수정하여 inode-number & unix-time-stamp가있는 줄을 파일에 추가 할 수 있습니다. 이제 그림이 아니라 선으로 그림을 검색하는 것이 훨씬 빠릅니다. 또는 사진을 디스크에 저장할 때마다 타임 스탬프 파일에 줄을 추가합니다. 라운드 솔루션. 그러나 현재 사진의 문제를 해결하지 못하므로 질문이 관련됩니다.

@hhh 어떤 파일 시스템을 사용하고 있습니까? 또는 중요하지 않습니다 ... ext에는 기본적으로 설정되어 있지 않은 일부 성능 향상 기능이 있습니다. 아마도 그조차도 당신이 말하는 규모로 다루지 않을 것입니다. DB는 이러한 것들에 최적화되어 있으며이를 처리하기위한 다양한 색인 솔루션이 있습니다. 예를 들어, btree 인덱스는 단순한 배열이 아닙니다.
xenoterracide

@ xenoterracide : ext3, 중요한지 확실하지 않습니다. 내가 설명 한 솔루션이 향후 검색 문제의 문제를 해결한다고 생각하지만 현재 사진에서는 전혀 도움이되지 않으므로 검색하는 데 시간이 많이 걸립니다.

1
단일 디렉토리에 수백만 개의 파일이 있습니까? 그렇다면 파일 이름의 첫 문자를 기준으로 한 두 수준의 하위 하위 디렉터리로 나누는 것을 고려할 수 있습니다.a/b/abcdef.jpg
alex

답변:


4

다른 껍질을 사용해보십시오. 예를 들어 zsh 를 사용하고 더 많은 매개 변수를 허용하는지 확인하는 것이 좋습니다 .

올바르게 이해하면 파일 이름의 일부가 UNIX 타임 스탬프입니다. 파일을 폴더로 나누는 것이 좋습니다. 날짜 / 시간 형식이 UNIX 에포크 (epoch) 번호 인 경우 해당 폴더의 소수 (예 : 10000)를 별도의 폴더에 넣으십시오.

ISO 8601 타임 스탬프가 파일 이름의 일부인 경우 연도, 월 또는 일로 간단히 나눕니다.


1
ls와 find는 bash 나 zsh에 내장되어 있지 않으므로이 경우 쉘 전환이 어떻게 도움이되는지 확실하지 않습니다.
Robin Green

쉘 확장에 관한 것입니다. 쉘이 globbing을 확장 할 수 없다면 이것이 문제 일 수 있습니다.
polemon

약 1e6 파일에서 명령을 실행하는 테스트를 거의하지 않았으며 ZSH는 동일한 문제에 직면합니다 "$ cp * Test/ ksh: cp: Argument list too long % rm * zsh: sure you want to delete all the files in /home/user/Downloads [yn]? y zsh: argument list too long: rm % ls * zsh: argument list too long: ls ". 죄송하지만 테스트하기 쉽고 1e6 파일 만 만들고 명령을 실행하기 때문에 이것이 질문 -1과 어떻게 관련되어 있는지 알 수 없습니다.

1

것이다 locate(물론 updatedb) 당신에게 어떤 도움이 될?


1
updatedb을 사용합니다 find.
dave1010

@ dave1010, 그러나 그것은 배경에서 가끔씩 그렇게합니다. 따라서 OP가 허용 할 수 있다면 매분마다 최신 상태가 아니지만 하루에 한 번 업데이트해야하며 조용한 시간에 업데이트 된 일정을 예약하십시오 (또는 자주 업데이트되지만 우선 순위가 낮은 일정을 예약하십시오 (어쨌든 있어야 함) .locate를 사용하면 원하는 것을 빨리 찾을 수 있습니다. 따라서 중요한 질문은 DB (또는 다른 시스템의 색인)가 얼마나 최신 상태 여야하는지입니다.
asoundmove
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.