2012-09-24 31 views
2

我有一個包含幾千個文件的目錄。我希望能夠在較大的導演中創建子目錄,並將剛剛創建的目錄中的150個文件(通過擴展名篩選)移動到每個新目錄中。我會喜歡一些指導讓我走。這是我開始的小事:每x個文件;創建新的目錄並移動文件 - 使用Python

wd = os.chdir(r'foobar') 

allgzs=[] 

for file in os.listdir(wd): 
    if file.endswith('asc.gz'): 
     allgzs.append(file) 

for gz in allgzs: 


# For every 150 .gz files: 
# Create directory -- os.mkdir? 
# Move files into directory -- shutil.move? 

回答

2

一個grouper功能的產量爲n運行長序列:

import itertools 
def grouper(S, n): 
    iterator = iter(S) 
    while True: 
     items = list(itertools.islice(iterator, n)) 
     if len(items) == 0: 
      break 
     yield items 

從那裏,你可以做你想做的很簡潔:

import glob, os, shutil 
fnames = sorted(glob.glob('*asc.gz')) 
for i, fnames in enumerate(grouper(fnames, 150)): 
    dirname = 'batch%d' % i 
    os.mkdir(dirname) 
    for fname in fnames: 
     shutil.move(fname, dirname) 
+0

你可能不需要'sorted',但'os.listdir'和'glob.glob'都是僞隨機出現的,這讓我感覺非常不直觀,所以我在我的例子中加入了它。 –

2

讓我們來看看,我會列舉我在這種情況下會做什麼。文件

  • 獲取列表 - X
  • 遍歷所有文件 - X
  • 確保文件只有一個週期 - Ø
  • 過濾掉不需要的擴展 - X
  • 添加希望擴展新列表 - O
  • 循環遍歷新列表中的所有文件 - O
  • 將它們添加到列表中並使用計數器,以便知道何時有150 - O
  • 當你有150個文件,將它們全部移動 - O
  • 回到循環 - O
  • 一旦你遍歷所有和複製,你就完成了。

你有它。此外,這絕不是最有效或最好的方式來做到這一點,這是我的方式。

編輯:示例代碼:

wantedexts = [".jpg",".png",".randomext"] 
wantedfiles = [] 

for f in files: #the files from the folder 
    allowedext = 0 
    for exts in wantedexts: 
     if f.endswith(exts): 
      allowedext = 1 
      break 
    if allowedext: 
     wantedfiles.append(f) 

counter = 0 
countertwo = 0 #used to tell when you get to the end of the files 
copyfiles = [] 
for f in wantedfiles: 
    if counter == 150 or countertwo == len(wantedfiles): 
     for fc in copyfiles: 
      copy #too lazy to type in real copy code 
     counter = 0 
     copyfiles = [] 
    copyfiles.append(f) 
    counter += 1 
    countertwo += 1 

差不多寫的代碼給你,但不管。 Countertwo用於複製最後的項目(因爲可能有一些遺留下來)。

+0

感謝您的工作流程大綱,這真的有所幫助。你能詳細說明櫃檯嗎? – KennyC

+0

嗯,這真是一個我編造的術語,雖然它是一個櫃檯。基本上它是循環外的整數(所以它不會在每次循環時重置)。因此,對於循環所經歷的每個文件,將1添加到計數器。你在循環中做的第一件事是檢查計數器是否在150.如果是,移動文件,然後繼續循環的正常操作。如果你喜歡,我可以提供示例代碼。 – Mitch

+0

這將是了不起的。我在閱讀完您的工作流程後也編輯了操作 – KennyC

0

可以使用glob模塊這個

for file in glob.glob('*.gz'): 
    #Do Stuff 
1

我只是用一個列表理解,使文件名列表在這裏。您的列表將來自os.listdirglob.glob('*asc.gz')

>>> files = ['foo{}.gz'.format(i) for i in range(5000)] 
>>> for i, fname in enumerate(files): 
...  if i%150 == 0: 
...   dirname = "bar{}".format(i//150) 
...   os.mkdir(dirname) 
...  print fname,"-->", dirname 
...  shutil.move(fname, dirname) 
... 
foo0.gz --> bar0 
foo1.gz --> bar0 
foo2.gz --> bar0 
foo3.gz --> bar0 
foo4.gz --> bar0 
foo5.gz --> bar0 
... 

這裏的竅門是150保持我們正在處理的文件和鴻溝計數它映射到目錄中。 //只是意味着整數除法(同Python2 /

1

如果你熱衷於讓你已經寫代碼,這裏是一個直觀的方式來完成它:我想出了

import os 
import shutil 

wd = os.chdir(r'foobar') 

allgzs=[] 

for file in os.listdir(wd): 
    if file.endswith('asc.gz'): 
     allgzs.append(file) 

n = 1 
name = "subdir%i" %n 
for gz in allgzs: 
    if not os.path.exists(name): 
     os.mkdir(name) 
    shutil.move(gz, name) 
    if len(os.listdir(name)) == 150: 
     n += 1 
     name = "subdir%i" %n 
+0

您應該繼續,現在在您的示例中導入'os'和'shutil',而不是單獨提醒(注意:它是「shutil」,而不是「shutils」)。 –

+0

是的。感謝您的建議。 – Karol

+0

@MuMind感謝您考慮我的問題。我試圖實現你的例子,它通過第一次工作,但第二次迭代失敗'OSLerror:[Errno 20] Nota目錄:foo'行'if len(os.listdir(foo))''任何想法? – KennyC

相關問題