Как скопировать файлы в папки на основе файла, содержащего имя папки? - PullRequest
0 голосов
/ 23 октября 2018

Python версия: 2.7.13

ОС: Windows

Поэтому я пишу скрипт для копирования файлов с разными именами в определенную папку, исходя из требования, что они содержат папкуимя внутри имени файла.(Я довольно новичок в этом, просто пытаюсь создать сценарии для большей эффективности в моей работе - я просмотрел тонну страниц StackOverflow и некоторых мест в Интернете, но не смог найти что-то связанное с Python для этой конкретной задачи)

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

По существу, "если таковые имеются (x в dirName для x в списке):","переместить файл в x".

Что касается sourceFolder и destFolder, это переменные, полученные из пользовательского ввода ранее в коде.(sourceFolder содержит файлы, destFolder содержит подпапки, в которые я копирую)

РЕДАКТИРОВАТЬ: у меня есть несколько подпапок в destFolder, я могу получить файлы для копирования, если они соответствуют строке, (если нет совпаденийнастоящее, они не копируют).Однако, когда они копируют, все они переходят в одну и ту же подпапку.

list=[]

if var == "y": #Checks for 'Yes' answer
    for subdir, dirs, files in os.walk(destFolder):
        subdirName = subdir[len(destFolder) + 1:] #Pulls subfolder names as strings
        print subdirName
        list.insert(0, subdirName)
        print "Added to list"


for subdir, dirs, files in os.walk(sourceFolder):
        for file in files:
            dirName = os.path.splitext(file)[0] #This is the filename without the path
            destination = "{0}\{1}".format(destFolder, subdirName)

            string = dirName #this is the string we're looking in
            if any(x in dirName for x in list):
                print "Found string: " + dirName
                shutil.copy2(os.path.join(subdir, file), destination)
            else:
                print "No String found in: " + dirName

РЕДАКТИРОВАТЬ 2: После некоторой настройки и помощи извне, вот что я закончил с рабочим кодом (радииз всех, кто сталкивался с этим).Некоторые переменные изменили имена, но, надеюсь, структура будет читабельной.

import shutil, os, re, stat из os import listdir из os.path import isfile, join

destKey = dict ()

if var == "y": #Checks for 'Yes' answer
    for root, dirs, files in os.walk(destFolder):
        for dest_folder in dirs: #This is the folder, for each we look at
            destKey[dest_folder] = os.path.join(root, dest_folder) #This is where we convert it to a dictionary with a key

for sourceFile in os.listdir(sourceFolder):
    print ('Source File: {0}').format(sourceFile)
    sourceFileName = os.path.basename(sourceFile) #filename, no path
    for dest_folder_name in destKey.keys():
        if dest_folder_name in sourceFileName.split('-'): #checks for dest name in sourceFile
            destination = destKey[dest_folder_name]
            print "Key match found for" + dest_folder_name
            shutil.copy2(os.path.join(sourceFolder, sourceFile), destination)
            print "Item copied: " + sourceFile

Ответы [ 3 ]

0 голосов
/ 23 октября 2018

Я старался держать его как можно ближе к исходному коду.Мы бросаем любые файлы, в которых есть имя папки, в соответствующую папку.Мы не повторяем какие-либо файлы в ходе обхода всех каталогов с использованием кэша набора.

import os, shutil

dirs_ls = []

destFolder = 'Testing'
for subdir, dirs, files in os.walk(destFolder):
    subdirName = subdir[len(destFolder) + 1:]  # Pulls subfolder names as strings
    dirs_ls.append(subdirName)

dirs_ls = filter(None, dirs_ls)

copied_files = set()
for subdir, dirs, files in os.walk(destFolder):
    for file_name in files:
        if file_name in copied_files:
            continue

        file_name_raw = file_name.split('.')[0]

        for dir in dirs_ls:
            if dir not in file_name_raw:
                continue
            shutil.copy2(os.path.join(destFolder, file_name), os.path.join(destFolder, file_name_raw))
            copied_files.add(file_name)

Структура каталогов до запуска сценария:

.
├── bro
├── bro.txt
├── foo
├── foo.txt
├── yo
└── yo.txt

Структура каталогов после запуска сценария:

.
├── bro
│   └── bro.txt
├── bro.txt
├── foo
│   └── foo.txt
├── foo.txt
├── yo
│   └── yo.txt
└── yo.txt
0 голосов
/ 24 октября 2018

Ваше решение использует any (), чтобы определить, соответствует ли файл какой-либо из подкаталогов, а затем перемещает файл к последнему значению, сохраненному в subdir.И обратите внимание, как subdirName последний раз устанавливается в предыдущем цикле , поэтому его значение никогда не изменится во втором цикле.Я также вижу несколько других проблем.Вам нужен список имен подкаталогов, но затем вам также нужен список полных относительных путей, предполагая, что destFolder и sourceFolder не совпадают и имеют подкаталоги.Также лучше не перезаписывать базовые типы, такие как list, своим именем переменной.Попробуйте это:

from os.path import dirname, join, splitext
from os import walk

dir_list = []
if var == "y": #Checks for 'Yes' answer
    for subdir, dirs, files in walk(destFolder):
        dir_list.append(subdir)  # keeping the full path, not just the last directory
        print 'Added "{0}" to the list'.format(subdir)

for subdir, dirs, files in walk(sourceFolder):
    for file in files:
        fname = splitext(file)[0]  # This is the filename without the path
        for dpath in dir_list:
            # Fetch last directory in the path
            dname = dirname(dpath)
            if dname in fname:
                # Directory name was found in the file name; copy the file
                destination = join(destFolder, dpath, file)
                shutil.copy2(join(subdir, file), destination)

Я не проверял выше, но это должно дать вам представление о том, как сделать эту работу.

0 голосов
/ 23 октября 2018

Вот как я бы сделал сравнение:

list = ["abc", "def", "ghi"]

dirname = "abcd"
for x in list:
    if x in dirname:
        print(dirname, x)

Итак, ваш код будет выглядеть так:

for subdir, dirs, files in os.walk(sourceFolder):
    for file in files:
        dirName = os.path.splitext(file)[0] #This is the filename without the path
        destination = "{0}\{1}".format(destFolder, subdirName)

        for x in list:
            if x in dirName:
                print "Found string: " + dirName
                shutil.copy2(os.path.join(subdir, file), destination)
            else:
                print "No String found in: " + dirName

Решает ли это проблему?

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...