2013-03-10 3 views
2

Интересно, дает ли python канонический способ скопировать файл в каталог с его оригинальными ведущими каталогами, например cp --parents. От cp человек страницы:Скопируйте файл в каталог с его оригинальными ведущими каталогами, добавленными

`--parents' 
[...] 
    cp --parents a/b/c existing_dir 

copies the file `a/b/c' to `existing_dir/a/b/c', creating any 
missing intermediate directories. 

Я ничего в shutil документации, которая относится к этому не видно. Конечно, я мог бы создать всю структуру каталогов в каталоге existing_dir, прежде чем копировать в нее любой файл, но, возможно, это накладные расходы.

+0

Я думаю, что это такие вещи, вы программируете себя в состоянии найти библиотеку, которые имеют эту функцию. Это зависит от относительных путей, в то время как вещи на 'shutil' не должны – JBernardo

+0

Посмотрите на документы для 'os' - похоже, вы хотите эмулировать 'mkdir -p' для пути, а затем скопировать файл в него ? –

+0

@ Джонатан Ванаско: Да, вот и все. – michaelmeyer

ответ

1

Я наконец придумал следующий код. Он действует почти так же, как и cp --parents.

import os, shutil 

def cp_parents(target_dir, files): 
    dirs = [] 
    for file in files: 
     dirs.append(os.path.dirname(file)) 
    dirs.sort(reverse=True) 
    for i in range(len(dirs)): 
     if not dirs[i] in dirs[i-1]: 
      need_dir = os.path.normpath(target_dir + dirs[i]) 
      print("Creating", need_dir) 
      os.makedirs(need_dir) 
    for file in files: 
     dest = os.path.normpath(target_dir + file) 
     print("Copying %s to %s" % (file, dest)) 
     shutil.copy(file, dest) 

Зов это следующим образом:

target_dir = '/tmp/dummy' 
files = [ '/tmp/dir/file1', '/tmp/dir/subdir/file2', '/tmp/file3' ] 

cp_parents(target_dir, files) 

Выход:

Creating /tmp/dummy/tmp/dir/subdir 
Copying /tmp/dir/file1 to /tmp/dummy/tmp/dir/file1 
Copying /tmp/dir/subdir/file2 to /tmp/dummy/tmp/dir/subdir/file2 
Copying /tmp/file3 to /tmp/dummy/tmp/file3 

Существует, вероятно, лучший способ справиться с этим, но это работает.

0

Не уверен, что вам нужно, но звучит как shutil.copytree. Вы можете увидеть все документы here, но в основном все, что вам нужно вызвать в вашем примере это что-то вроде

shutil.copytree('a/b/c', 'existing_dir/a/b/c') 
+0

На самом деле 'shutil.copytree' копирует все исходное дерево, а то, что я хочу, - это копировать только некоторые файлы из него. – michaelmeyer

+0

О, был уверен, что он копировал только файлы из указанного вами каталога и более глубокого EDIT: перечитывать, неправильно интерпретировать c как каталог в своем ответе, не понимал, что вы предназначались для него как файл –

0
import os 
import shutil 

files = [ '/usr/bin/ls','/etc/passwd' , '/var/log/daily.out' , '/var/log/system.log' , '/var/log/asl/StoreData' ] 

def copy_structure(dst_dir,source_files): 
    if not os.path.exists(dst_dir) and os.path.isdir(dst_dir): 
     os.mkdir(dst_dir) 
    for file in source_files: 
     dir_name = os.path.dirname(file) 
     final_dir_path = os.path.normpath(dst_dir+dir_name) 
     if not os.path.exists(final_dir_path): 
      os.makedirs(final_dir_path)    
     if os.path.exists(file): 
      shutil.copy(file,final_dir_path) 

copy_structure('/tmp/backup',files) 
0

только 3,6 или выше (она использует функцию ф)

Это моя реализация ф --parents

Первые получают коррекции для получения СРКА каталогов и имени файла, а также для (иногда мне хотелось опустить первую папку файла src)

Затем он извлекает папки и имя файла (проверка в src_dirs происходит потому, что я заметил, что когда файл src не был вложен в любую папку, он разбился)

Наконец он создает дерево каталогов в папку назначения и копирует в него файл

def __copy_parents(src, dest_folder, dir_offset=0): 
    ''' Copies src tree into dest, offset (optional) omits n folders of the src path''' 
    prev_offset = 0 if dir_offset == 0 else src.replace('/', '%', dir_offset - 1).find('/') + 1 
    post_offset = src.rfind('/') 

    src_dirs = '' if post_offset == -1 else src[prev_offset:post_offset] 
    src_filename = src[post_offset + 1:] 

    os.makedirs(f'{dest_folder}/{src_dirs}', exist_ok=True) 
    shutil.copy(src, f'{dest_folder}/{src_dirs}/{src_filename}') 
Смежные вопросы