2016-02-12 1 views
0

J'ai un répertoire volumineux avec de nombreux fichiers de pièces avec leurs révisions, je veux créer de manière récursive un nouveau dossier pour chaque partie, puis déplacer tous les fichiers liés dans ce dossier. J'essaie de le faire en isolant un numéro à 7 chiffres qui serait utilisé comme identifiant pour la pièce, et tous les noms de fichiers associés incluraient également ce numéro.Création de sous-répertoires et tri de fichiers basés sur le nom de fichier PYTHON

import os 
import shutil 
import csv 
import glob 
from fnmatch import fnmatch, filter 
from os.path import isdir, join 
from shutil import copytree, copy2, Error, copystat 
from shutil import copytree, ignore_patterns 


dirname = ' ' 

# pattern = '*???????*' 

for root, dirs, files in os.walk(dirname): 
    for fpath in files: 
     print(fpath) 
     if fpath[0:6].isdigit(): 
      matchdir = os.mkdir(os.path.join(os.path.dirname(fpath))) 
      partnum = str(fpath[0:6]) 
      pattern = str(partnum) 
      filematch = fnmatch(files, pattern) 
      print(filematch) 
      shutil.move(filematch, matchdir) 

C'est ce que j'ai à ce jour, au fond, je ne suis pas sûr comment obtenir le nom du fichier d'origine et l'utiliser comme le crépitement correspondant pour le reste des fichiers. Le nom de fichier d'origine que je veux utiliser pour ce motif correspondant est juste un nombre à 7 chiffres, et tous les fichiers associés peuvent avoir d'autres caractères (REV-2) par exemple.

+0

Où avez-vous des problèmes? Vous avez réussi à extraire un numéro à 7 chiffres du début du nom de fichier, à l'enregistrer dans ** partnum ** et ** pattern ** et à rechercher d'autres fichiers contenant cette chaîne à 7 chiffres. Le nom du fichier d'origine est toujours sûr dans ** fpath **. Quelle partie de cela ne fonctionne pas, et que fait-elle * à la place? – Prune

Répondre

1

Ne pas overthink il

Je pense que vous obtenez confus au sujet de ce que os.walk() vous donne - revérifier le docs. dirs et files sont juste une liste de noms des répertoires/fichiers, pas les chemins complets.

Voici ma suggestion. En supposant que vous commencez avec une mise en page de répertoire quelque chose comme:

directory1 
    1234567abc.txt 
1234567abc.txt 
1234567bcd.txt 
2234567abc.txt 
not-interesting.txt 

et que vous voulez finir avec quelque chose comme:

directory1 
    1234567 
     abc.txt 
1234567 
    abc.txt 
    bcd.txt 
2234567 
    abc.txt 
not-interesting.txt 

Si c'est exact, alors il n'y a pas besoin de rematch les fichiers dans le répertoire , il suffit d'opérer sur chaque fichier individuellement, et de faire le répertoire de la pièce seulement s'il n'existe pas déjà. Je voudrais aussi utiliser une expression régulière pour ce faire, si quelque chose comme:

import os 
import re 
import shutil 

for root, dirs, files in os.walk(dirname): 
    for fname in files: 
     # Match a string starting with 7 digits followed by everything else. 
     # Capture each part in a group so we can access them later. 
     match_object = re.match('([0-9]{7})(.*)$', fname) 
     if match_object is None: 
      # The regular expression did not match, ignore the file. 
      continue 

     # Form the new directory path using the number from the regular expression and the current root. 
     new_dir = os.path.join(root, match_object.group(1)) 
     if not os.path.isdir(new_dir): 
      os.mkdir(new_dir) 

     new_file_path = os.path.join(new_dir, match_object.group(2)) 

     # Or, if you don't want to change the filename, use: 
     new_file_path = os.path.join(new_dir, fname) 

     old_file_path = os.path.join(root, fname) 
     shutil.move(old_file_path, new_file_path) 

Notez que je:

  • Switched le sens de l'état, nous continuons la boucle immédiatement si le fichier est pas intéressant. C'est un modèle utile à utiliser pour s'assurer que votre code ne soit pas trop indenté.
  • A changé le nom de fpath en fname. C'est parce que ce n'est pas un chemin mais juste le nom du fichier, il est donc préférable de l'appeler fname.

Veuillez clarifier la question si ce n'est pas ce que vous vouliez dire! [Edit] pour montrer comment copier le fichier sans changer son nom.

+0

Merci! Comment pourrais-je changer cela pour inclure les fichiers qui ne commencent pas avec le numéro? J'ai essayé d'ajouter un '*' avant le ([0-9] {7}) (. *) $ Mais j'ai eu une erreur – Darya

+0

Pour une raison quelconque, quand les fichiers sont déplacés, leurs noms (qui sont le nom du répertoire) sont supprimés. Je pense que le code prend les caractères des noms de fichiers pour créer les noms de répertoires, mais je ne veux pas que le nom du fichier soit modifié. Comment puis-je réparer cela? – Darya

+0

Si vous voulez faire correspondre des fichiers qui contiennent seulement 7 nombres, alors au lieu de faire 're.match (pattern, string)' vous pouvez faire 're.search (pattern, string)', qui correspondra si 'string' contient' pattern' n'importe où dedans.Pour mieux comprendre les expressions régulières, consultez le tutoriel [regular-expressions-info] (http://www.regular-expressions.info/tutorial.html), c'est ce que j'ai appris, et assurez-vous de lire le python [ regex docs] (https://docs.python.org/2/library/re.html). – daphtdazz