web-dev-qa-db-fra.com

Renommez plusieurs fichiers dans un répertoire dans Python

J'essaie de renommer certains fichiers d'un répertoire à l'aide de Python.

Supposons que j’ai un fichier appelé CHEESE_CHEESE_TYPE.*** et que je souhaite supprimer CHEESE_ afin que mon nom de fichier résultant soit CHEESE_TYPE

J'essaie d'utiliser le os.path.split mais cela ne fonctionne pas correctement. J'ai également envisagé d'utiliser des manipulations de chaîne, mais je n'ai pas réussi non plus.

396
Jeff

Utilisez os.rename(src, dst) pour renommer ou déplacer un fichier ou un répertoire.

$ ls
cheese_cheese_type.bar  cheese_cheese_type.foo
$ python
>>> import os
>>> for filename in os.listdir("."):
...  if filename.startswith("cheese_"):
...    os.rename(filename, filename[7:])
... 
>>> 
$ ls
cheese_type.bar  cheese_type.foo
629
Messa

Voici un script basé sur votre dernier commentaire.

#!/usr/bin/env python
from os import rename, listdir

badprefix = "cheese_"
fnames = listdir('.')

for fname in fnames:
    if fname.startswith(badprefix*2):
        rename(fname, fname.replace(badprefix, '', 1))
37
bukzor

Le code suivant devrait fonctionner. Il prend chaque nom de fichier dans le répertoire actuel, si le nom de fichier contient le motif CHEESE_CHEESE_, il est renommé. Sinon, rien n'est fait pour le nom de fichier.

import os
for fileName in os.listdir("."):
    os.rename(fileName, fileName.replace("CHEESE_CHEESE_", "CHEESE_"))
18
Yogeesh Seralathan

En supposant que vous êtes déjà dans le répertoire et que les "8 premiers caractères" de votre commentaire sont toujours valables. (Bien que "CHEESE_" ait 7 caractères ...? Si oui, changez le 8 en 7)

from glob import glob
from os import rename
for fname in glob('*.prj'):
    rename(fname, fname[8:])
15
darelf

J'ai le même problème, où je veux remplacer l'espace blanc de n'importe quel fichier pdf par un tiret -. Mais les fichiers étaient dans plusieurs sous-répertoires. Donc, je devais utiliser os.walk(). Dans votre cas pour plusieurs sous-répertoires, cela pourrait ressembler à ceci:

import os
for dpath, dnames, fnames in os.walk('/path/to/directory'):
    for f in fnames:
        os.chdir(dpath)
        if f.startswith('cheese_'):
            os.rename(f, f.replace('cheese_', ''))
11
Aziz Alto

Essaye ça:

import os
import shutil

for file in os.listdir(dirpath):
    newfile = os.path.join(dirpath, file.split("_",1)[1])
    shutil.move(os.path.join(dirpath,file),newfile)

Je suppose que vous ne voulez pas supprimer l'extension de fichier, mais vous pouvez simplement faire la même division avec des points.

7
krs1

Ce type de matériel est parfaitement adapté à IPython, qui intègre Shell.

In [1] files = !ls
In [2] for f in files:
           newname = process_filename(f)
           mv $f $newname

Remarque: pour stocker cela dans un script, utilisez l'extension .ipy et préfixez toutes les commandes du shell avec !.

Voir aussi: http://ipython.org/ipython-doc/stable/interactive/Shell.html

6
Erik Allik

Cette commande supprimera la chaîne initiale "= CHEESE_" initiale de tous les fichiers du répertoire en cours, en utilisant renamer :

$ renamer --find "/^CHEESE_/" *
4
Lloyd

Voici une solution plus générale:

Ce code peut être utilisé pour supprimer de manière récurrente tout caractère ou jeu de caractères particulier de tous les noms de fichiers d’un répertoire et les remplacer par tout autre caractère, jeu de caractères ou aucun caractère.

import os

paths = (os.path.join(root, filename)
        for root, _, filenames in os.walk('C:\FolderName')
        for filename in filenames)

for path in paths:
    # the '#' in the example below will be replaced by the '-' in the filenames in the directory
    newname = path.replace('#', '-')
    if newname != path:
        os.rename(path, newname)
4
nicholas

Il semble que votre problème réside davantage dans la détermination du nouveau nom de fichier que du changement de nom lui-même (pour lequel vous pouvez utiliser la méthode os.rename).

Votre question ne dit pas clairement quelle est la tendance que vous souhaitez renommer. Il n'y a rien de mal avec la manipulation de chaîne. Une expression régulière peut être ce dont vous avez besoin ici.

4
Uri

Au départ, je recherchais une interface graphique permettant de renommer des expressions régulières et offrant un aperçu du résultat avant l'application des modifications.

Sur Linux, j’ai utilisé avec succès krename , sous Windows Total Commander renomme avec des expressions rationnelles, mais je n’ai trouvé aucun équivalent libre décent pour OSX. J’ai donc fini par écrire un script python qui fonctionne. récursivement et par défaut, imprime uniquement les nouveaux noms de fichier sans apporter de modifications. Ajoutez le commutateur '-w' pour modifier les noms de fichiers.

#!/usr/bin/python
# -*- coding: utf-8 -*-

import os
import fnmatch
import sys
import shutil
import re


def usage():
    print """
Usage:
        %s <work_dir> <search_regex> <replace_regex> [-w|--write]

        By default no changes are made, add '-w' or '--write' as last arg to actually rename files
        after you have previewed the result.
        """ % (os.path.basename(sys.argv[0]))


def rename_files(directory, search_pattern, replace_pattern, write_changes=False):

    pattern_old = re.compile(search_pattern)

    for path, dirs, files in os.walk(os.path.abspath(directory)):

        for filename in fnmatch.filter(files, "*.*"):

            if pattern_old.findall(filename):
                new_name = pattern_old.sub(replace_pattern, filename)

                filepath_old = os.path.join(path, filename)
                filepath_new = os.path.join(path, new_name)

                if not filepath_new:
                    print 'Replacement regex {} returns empty value! Skipping'.format(replace_pattern)
                    continue

                print new_name

                if write_changes:
                    shutil.move(filepath_old, filepath_new)
            else:
                print 'Name [{}] does not match search regex [{}]'.format(filename, search_pattern)

if __== '__main__':
    if len(sys.argv) < 4:
        usage()
        sys.exit(-1)

    work_dir = sys.argv[1]
    search_regex = sys.argv[2]
    replace_regex = sys.argv[3]
    write_changes = (len(sys.argv) > 4) and sys.argv[4].lower() in ['--write', '-w']
    rename_files(work_dir, search_regex, replace_regex, write_changes)

Exemple d'utilisation

Je souhaite retourner les parties d’un nom de fichier de la manière suivante, c’est-à-dire déplacer le bit m7-08 au début du nom de fichier:

# Before:
Summary-building-mobile-apps-ionic-framework-angularjs-m7-08.mp4

# After:
m7-08_Summary-building-mobile-apps-ionic-framework-angularjs.mp4

Cela effectuera un essai et imprimera les nouveaux noms de fichier sans renommer aucun fichier:

rename_files_regex.py . "([^\.]+?)-(m\\d+-\\d+)" "\\2_\\1"

Cela fera le renommage réel (vous pouvez utiliser soit -w ou --write):

rename_files_regex.py . "([^\.]+?)-(m\\d+-\\d+)" "\\2_\\1" --write
3
ccpizza

import os import chaîne def rename_files ():

#List all files in the directory
file_list = os.listdir("/Users/tedfuller/Desktop/prank/")
print(file_list)

#Change current working directory and print out it's location
working_location = os.chdir("/Users/tedfuller/Desktop/prank/")
working_location = os.getcwd()
print(working_location)

#Rename all the files in that directory
for file_name in file_list:
    os.rename(file_name, file_name.translate(str.maketrans("","",string.digits)))

rename_files ()

3
Ted Fuller

Vous pouvez utiliser la fonction os.system pour plus de simplicité et d’appeler bash pour accomplir la tâche suivante:

import os
os.system('mv old_filename new_filename')
2
user5449023

Et ça :

import re
p = re.compile(r'_')
p.split(filename, 1) #where filename is CHEESE_CHEESE_TYPE.***
0
Bandan

Cela fonctionne pour moi.

import os
for afile in os.listdir('.'):
    filename, file_extension = os.path.splitext(afile)
    if not file_extension == '.xyz':
        os.rename(afile, filename + '.abc')
0
edib