Directory slicer

Делитель папки

Розділювач папки


Splits directory/subdirectories to pieces of given size.
Pieces placed to subdirectories with names 001 ... 999.
Moved files list written to list.txt.
Usage : slice_dir.py dir size
Where dir - input directory, size - chunks size in bytes.

Делит папку на подпапки заданного размера.
Куски размещаются в подпапки с названиями 001 ... 999.
Список перемещенных файлов пишется в list.txt.
Использование : slice_dir.py dir size
Где dir - входная папка, size - размер подпапок, байтов.

Ділить папку на підпапки заданого розміру.
Шматки розміщуються в підпапки з назвами 001 ... 999
Список переміщених файлів пишеться в list.txt.
Використання : slice_dir.py dir size
Де dir - вхідная папка, size - размір підпапок, байтів.



#!/usr/bin/python

import os, os.path, sys, shutil, fnmatch, pprint

if len(sys.argv) != 3:
  print 'Directory splitter.'
  print 'Splits directory to subdirectories of given size.'
  print 'Pieces placed to subdirectories with names 001 ... 999.'
  print 'Moved files list written to list.txt.'
  print 'Usage : ', os.path.split(sys.argv[0])[1],' dir size'
  print 'Where dir - input directory, size - chunks size in bytes.'
else :
  dir_in = os.path.abspath(sys.argv[1]) #input directory
  dir_out = os.path.abspath(sys.argv[1]) #output root directory
  chunk_size = int(sys.argv[2]) #one files chunk size

  chunk_used_size = 0 #number of bytes used in current chunk
  chunk_num = 0 #chunk dirs counter

  files_num = 0 #number of found files
  files_list = [] #generated file list in form of array of tuples (file_abs_path_in, file_abs_path_out)
  total_size = 0 #total size of all files
  list_file_name = 'list.txt' #generated list file name

  #walk all subfolders of input folder
  for root, dirs, files in os.walk(dir_in) :
    for file_name in files : #iterate for each file in folder
      files_num += 1 #files counter
      file_in_path_abs = os.path.join(root, file_name) #absolute path to input file
      file_size = os.path.getsize(file_in_path_abs) #size of input file
      total_size += file_size #increment total size of files
      if (chunk_used_size + file_size) > chunk_size : #chunk size overflow - create next chunk folder
        chunk_num += 1
        chunk_used_size = 0
      chunk_used_size += file_size #bytes used in current chunk
      dir_out_cur = os.path.join(dir_out, str(chunk_num + 1).rjust(3, '0')) #output directory name generation
      #relative path to current file in input directory
      if root.startswith(dir_in) : dir_out_rel = root.replace(dir_in, '').lstrip('/').lstrip('\\')
      else : dir_out_rel = ''
      dir_out_abs = os.path.join(dir_out_cur, dir_out_rel) #calculate absolute path to output file
      file_out_path_abs = os.path.join(dir_out_abs, file_name)
      files_list.append((file_in_path_abs, file_out_path_abs)) #append (file_in, file_out) tuple to files list

  print 'Files : ', files_num, ', total size : ', total_size, ', total chunks : ', chunk_num+1, ', last chunk uses : ', chunk_used_size, ' bytes'
  open(list_file_name, 'wb', 1).write(pprint.pformat(files_list)) #write files list

  print 'Move files to output chunk folders (y/n) ? ',
  s = raw_input()
  if (s == 'y') or (s == 'Y') :
    for file_in, file_out in files_list :
      dir_out_abs = os.path.split(file_out)[0]
      if not os.path.lexists(dir_out_abs) : os.makedirs(dir_out_abs) #create output folder if not exists
      try: shutil.move(file_in, file_out) #move file
      except: print 'Can\'t move ', os.path.split(file_in)[1], ' to ', dir_out_abs

  print 'Press any key to exit...'
  raw_input()