2016-12-06 58 views
1

我有一些軟件版本的樹,我需要保留最後的3個版本。刪除最近的3個版本的文件夾 - Python

我有樹的文件夾是這樣的:

版本:

文件夾:

'10 .7.0.290' ,'10 .7.0.289' ,'10 .7.0.281' ,'10 .7.0.278 」,'10 .7.0.275'

'10 .6.7.282' ,'10 .6.7.277' ,'10 .6.7.274' ,'10 .6.7.270'

我想保持每個版本的最後3個文件夾,例如在這種情況下,我想保持'10 .7.0.yyy「和'10 .6.7.xxx版」的最後3的:

'10 .7.0.290' ,'10 .7.0.289' ,'10 .7.0.281'

'10 .6.7.282' ,'10 .6.7.277' ,'10 .6.7.274'

和刪除:

'10 .7.0.278' ,'10 .7.0.275'

'10 .6.7.270'

,但我的劇本目前只保留每個版本的最後3沒有:

腳本:

import os 
import re 
import shutil 

versions = [] 
folders = [] 
a = os.listdir('.') 
a.sort(reverse=True) 
sorted(a) 

for fn in a: 
    folders.append(fn) 
    if os.path.isdir(fn): 
     version = (re.match('^([0-9]+\.[0-9]+\.[0-9]+).*', fn)).group(1) 
     if (version) not in versions: 
      versions.append(version) 

result = [] 


for version in versions: 
    temp = [] 
    for folder in folders: 
     if folder.startswith(version): 
      temp.append(folder) 

    result.append(temp) 
print result  

for version in result: 
    for i in range(max(len(version) - 3, 0)): 
     print version[i] 
# shutil.rmtree(version[i]) 

結果

10.7.0.290 #this files are deleted 
10.7.0.289 #this files are deleted 
10.6.7.282 #this files are deleted 

回答

0

像這樣的工作:

import os 
import shutil 

from collections import defaultdict 


versions = defaultdict(list) 
directories = next(os.walk('.'))[1] 
for directory in directories: 
    major, minor, patch, minor_patch = directory.split('.') 
    versions['{}.{}.{}'.format(major, minor, patch)].append(int(minor_patch)) 

for version, minor_patches in versions.items(): 
    minor_patches.sort(reverse=True) 
    to_remove = minor_patches[3:] 
    for minor_patch in to_remove: 
     path = '{}.{}'.format(version, minor_patch) 
     shutil.rmtree('./{}'.format(path)) 

例子:

[$:/tmp/folders] $ tree 
. 
├── 10.6.7.270 
├── 10.6.7.274 
├── 10.6.7.277 
├── 10.6.7.282 
├── 10.7.0.275 
├── 10.7.0.278 
├── 10.7.0.281 
├── 10.7.0.289 
├── 10.7.0.290 
└── folders.py 

9 directories, 1 file 
[$:/tmp/folders] $ python folders.py 
[$:/tmp/folders] $ tree 
. 
├── 10.6.7.274 
├── 10.6.7.277 
├── 10.6.7.282 
├── 10.7.0.281 
├── 10.7.0.289 
├── 10.7.0.290 
└── folders.py 

6 directories, 1 file 
+0

我有一個錯誤,如果我有一個文件夾與10.6.7.274.22 trown異常和中止...如果我有其他文件的文件夾與錯誤的名稱不xx.yy.zz.aa中止與erro波紋管 ValueError:需要多個值 –

1

讓我們指出所需的步驟。

  1. 使用os.listdir可以獲得給定路徑中所有目錄的列表。
  2. 通過切片清單對列表進行排序並獲取前3個目錄名稱
  3. 使用shutil.rmtree可以在循環中刪除它們。

因此,解決方案應該是:

from os import listdir 
import shutil 

directories_to_delete = sorted(listdir('desired/path'))[:3] 
for directory in directories_to_delete: 
    shutil.rmtree(directory) 
+1

通過串結果版本'10'被排序早於'9'考慮。 – niemmi

+0

我只考慮過提到的輸入。不過,你很合乎邏輯,我會盡快更新它。 –

1

你可以文件夾名稱轉換爲列表int。這將允許版本的正確排序,因此10被認爲晚於9。然後,您可以按相反順序對它們進行排序,並使用groupby根據3個第一組件對它們進行分組。然後每個組,你可以放棄第一3項與dropwhile並刪除其餘:

from itertools import groupby, dropwhile 

FOLDERS = [ 
    '10.7.0.290', '10.7.0.289', '10.7.0.281', '10.7.0.278', '10.7.0.275', 
    '10.6.7.282', '10.6.7.277', '10.6.7.274', '10.6.7.270' 
] 

components = ([int(x) for x in fn.split('.')] for fn in FOLDERS) 
for _, g in groupby(sorted(components, reverse=True), key=lambda x: x[:3]): 
    for _, fn in dropwhile(lambda x: x[0] < 3, enumerate(g)): 
     print 'Remove {}'.format('.'.join(str(x) for x in fn)) 

輸出:

Remove 10.7.0.278 
Remove 10.7.0.275 
Remove 10.6.7.270 
+0

其實我誤解了這個問題,你的一個是正確的,upvoted。 –