Wsadowa zmiana nazw plików w katalogu

102

Czy istnieje łatwy sposób zmiany nazwy grupy plików już zawartych w katalogu przy użyciu Pythona?

Przykład: Mam katalog pełen plików * .doc i chcę zmienić ich nazwy w spójny sposób.

X.doc -> „nowy (X) .doc”

Y.doc -> „nowy (Y) .doc”

Nate
źródło

Odpowiedzi:

115

Taka zmiana nazwy jest dość łatwa, na przykład w przypadku modułów os i glob :

import glob, os

def rename(dir, pattern, titlePattern):
    for pathAndFilename in glob.iglob(os.path.join(dir, pattern)):
        title, ext = os.path.splitext(os.path.basename(pathAndFilename))
        os.rename(pathAndFilename, 
                  os.path.join(dir, titlePattern % title + ext))

Możesz następnie użyć tego w swoim przykładzie w następujący sposób:

rename(r'c:\temp\xx', r'*.doc', r'new(%s)')

Powyższy przykład skonwertuje wszystkie *.docpliki w katalogu c:\temp\xxdo new(%s).doc, gdzie %sjest poprzednią nazwą bazową pliku (bez rozszerzenia).

DzinX
źródło
1
Jak jest %używany symbol w poleceniu os.path.join(dir, titlePattern % title + ext)? Wiem, że %jest przeznaczony do operacji modulo i jest również używany jako operator formatowania. Ale zwykle następuje po nim slub w fcelu określenia formatu. Dlaczego nic (spacja) nie występuje bezpośrednio po %tym poleceniu?
Shashank Sawant,
3
@ShashankSawant Rzeczywiście jest to operator formatowania. Zobacz Operacje formatowania ciągów, aby uzyskać dokumentację i przykładowe użycie.
DzinX,
133

Wolę pisać małe, pojedyncze linery dla każdej wymiany, którą muszę wykonać, zamiast tworzyć bardziej ogólny i złożony kod. Na przykład:

Spowoduje to zastąpienie wszystkich podkreśleń myślnikami w dowolnym nieukrytym pliku w bieżącym katalogu

import os
[os.rename(f, f.replace('_', '-')) for f in os.listdir('.') if not f.startswith('.')]
Cesar Canassa
źródło
4
O wiele łatwiejsze niż inne metody. Dlatego uwielbiam Pythona.
Dan Gayle,
Zmarnowałem dziś zbyt dużo czasu, próbując dowiedzieć się, dlaczego moje polecenie „zmiany nazwy” nie działa - powinienem był przyjść tutaj pierwszy! Świetna jedna linijka Pythonic!
Devin
Nie działa, ponieważ system Windows rename
zmienia
4
Świetnie, ale działa tylko z reżem bez sub reż.
Hill
jeśli dostaniesz, no such file errorpamiętaj, że os.renamepotrzebujesz pełnej ścieżki
Windsooon
22

Jeśli nie masz nic przeciwko używaniu wyrażeń regularnych, ta funkcja dałaby ci dużą moc przy zmianie nazw plików:

import re, glob, os

def renamer(files, pattern, replacement):
    for pathname in glob.glob(files):
        basename= os.path.basename(pathname)
        new_filename= re.sub(pattern, replacement, basename)
        if new_filename != basename:
            os.rename(
              pathname,
              os.path.join(os.path.dirname(pathname), new_filename))

Więc w twoim przykładzie możesz zrobić (zakładając, że jest to bieżący katalog, w którym znajdują się pliki):

renamer("*.doc", r"^(.*)\.doc$", r"new(\1).doc")

ale możesz też przywrócić początkowe nazwy plików:

renamer("*.doc", r"^new\((.*)\)\.doc", r"\1.doc")

i więcej.

tzot
źródło
11

Mam to po prostu zmienić nazwy wszystkich plików w podfolderach folderu

import os

def replace(fpath, old_str, new_str):
    for path, subdirs, files in os.walk(fpath):
        for name in files:
            if(old_str.lower() in name.lower()):
                os.rename(os.path.join(path,name), os.path.join(path,
                                            name.lower().replace(old_str,new_str)))

Zamieniam wszystkie wystąpienia old_str jakimkolwiek przypadkiem na new_str.

kiriloff
źródło
Ten kod jest naprawdę używany do zamiany dowolnej części tytułu pliku w katalogu.
geoJshaun
6

Spróbuj: http://www.mattweber.org/2007/03/04/python-script-renamepy/

Lubię, gdy moja muzyka, filmy i zdjęcia są nazywane w określony sposób. Kiedy pobieram pliki z Internetu, zwykle nie są one zgodne z moją konwencją nazewnictwa. Znalazłem się ręcznie zmieniając nazwę każdego pliku, aby pasowała do mojego stylu. To bardzo szybko się zestarzało, więc zdecydowałem się napisać program, który zrobi to za mnie.

Ten program może konwertować nazwę pliku na małe litery, zamieniać ciągi znaków w nazwie pliku na dowolne i przycinać dowolną liczbę znaków z przodu lub z tyłu nazwy pliku.

Dostępny jest również kod źródłowy programu.

xsl
źródło
1
Niestety link jest uszkodzony, czy ktoś wie, gdzie jest kod źródłowy?
ryanpcmcquen
6

Sam napisałem skrypt w Pythonie. Jako argumenty przyjmuje ścieżkę do katalogu, w którym znajdują się pliki i wzorzec nazewnictwa, którego chcesz użyć. Jednak zmienia nazwę, dołączając kolejną liczbę (1, 2, 3 itd.) Do podanego wzorca nazewnictwa.

import os
import sys

# checking whether path and filename are given.
if len(sys.argv) != 3:
    print "Usage : python rename.py <path> <new_name.extension>"
    sys.exit()

# splitting name and extension.
name = sys.argv[2].split('.')
if len(name) < 2:
    name.append('')
else:
    name[1] = ".%s" %name[1]

# to name starting from 1 to number_of_files.
count = 1

# creating a new folder in which the renamed files will be stored.
s = "%s/pic_folder" % sys.argv[1]
try:
    os.mkdir(s)
except OSError:
    # if pic_folder is already present, use it.
    pass

try:
    for x in os.walk(sys.argv[1]):
        for y in x[2]:
            # creating the rename pattern.
            s = "%spic_folder/%s%s%s" %(x[0], name[0], count, name[1])
            # getting the original path of the file to be renamed.
            z = os.path.join(x[0],y)
            # renaming.
            os.rename(z, s)
            # incrementing the count.
            count = count + 1
except OSError:
    pass

Mam nadzieję, że to działa dla Ciebie.

harisibrahimkv
źródło
5

Znajdź się w katalogu, w którym chcesz zmienić nazwę.

import os
# get the file name list to nameList
nameList = os.listdir() 
#loop through the name and rename
for fileName in nameList:
    rename=fileName[15:28]
    os.rename(fileName,rename)
#example:
#input fileName bulk like :20180707131932_IMG_4304.JPG
#output renamed bulk like :IMG_4304.JPG
Ajay Chandran
źródło
aby "być w katalogu ..." użyjos.chdir(path_of_directory)
MagTun
2
directoryName = "Photographs"
filePath = os.path.abspath(directoryName)
filePathWithSlash = filePath + "\\"

for counter, filename in enumerate(os.listdir(directoryName)):

    filenameWithPath = os.path.join(filePathWithSlash, filename)

    os.rename(filenameWithPath, filenameWithPath.replace(filename,"DSC_" + \
          str(counter).zfill(4) + ".jpg" ))

# e.g. filename = "photo1.jpg", directory = "c:\users\Photographs"        
# The string.replace call swaps in the new filename into 
# the current filename within the filenameWitPath string. Which    
# is then used by os.rename to rename the file in place, using the  
# current (unmodified) filenameWithPath.

# os.listdir delivers the filename(s) from the directory
# however in attempting to "rename" the file using os 
# a specific location of the file to be renamed is required.

# this code is from Windows 
frank__aguirre
źródło
2

Miałem podobny problem, ale chciałem dopisać tekst na początku nazwy wszystkich plików w katalogu i zastosowałem podobną metodę. Zobacz przykład poniżej:

folder = r"R:\mystuff\GIS_Projects\Website\2017\PDF"

import os


for root, dirs, filenames in os.walk(folder):


for filename in filenames:  
    fullpath = os.path.join(root, filename)  
    filename_split = os.path.splitext(filename) # filename will be filename_split[0] and extension will be filename_split[1])
    print fullpath
    print filename_split[0]
    print filename_split[1]
    os.rename(os.path.join(root, filename), os.path.join(root, "NewText_2017_" + filename_split[0] + filename_split[1]))
Amber Davis
źródło
1

co do mnie w moim katalogu mam wiele podkatalogów, każdy podkatalog ma wiele obrazów Chcę zmienić wszystkie obrazy podkatalogu na 1.jpg ~ n.jpg

def batch_rename():
    base_dir = 'F:/ad_samples/test_samples/'
    sub_dir_list = glob.glob(base_dir + '*')
    # print sub_dir_list # like that ['F:/dir1', 'F:/dir2']
    for dir_item in sub_dir_list:
        files = glob.glob(dir_item + '/*.jpg')
        i = 0
        for f in files:
            os.rename(f, os.path.join(dir_item, str(i) + '.jpg'))
            i += 1

(moja własna odpowiedź) https://stackoverflow.com/a/45734381/6329006

Jayhello
źródło
1
#  another regex version
#  usage example:
#  replacing an underscore in the filename with today's date
#  rename_files('..\\output', '(.*)(_)(.*\.CSV)', '\g<1>_20180402_\g<3>')
def rename_files(path, pattern, replacement):
    for filename in os.listdir(path):
        if re.search(pattern, filename):
            new_filename = re.sub(pattern, replacement, filename)
            new_fullname = os.path.join(path, new_filename)
            old_fullname = os.path.join(path, filename)
            os.rename(old_fullname, new_fullname)
            print('Renamed: ' + old_fullname + ' to ' + new_fullname
Dan
źródło
1

Jeśli chcesz zmodyfikować nazwy plików w edytorze (takim jak vim), biblioteka kliknięć zawiera polecenie click.edit(), które może być używane do odbierania danych wejściowych użytkownika z edytora. Oto przykład tego, jak można go użyć do refaktoryzacji plików w katalogu.

import click
from pathlib import Path

# current directory
direc_to_refactor = Path(".")

# list of old file paths
old_paths = list(direc_to_refactor.iterdir())

# list of old file names
old_names = [str(p.name) for p in old_paths]

# modify old file names in an editor,
# and store them in a list of new file names
new_names = click.edit("\n".join(old_names)).split("\n")

# refactor the old file names
for i in range(len(old_paths)):
    old_paths[i].replace(direc_to_refactor / new_names[i])

Napisałem aplikację wiersza poleceń, która używa tej samej techniki, ale zmniejsza zmienność tego skryptu i ma więcej opcji, takich jak refaktoryzacja rekurencyjna. Oto link do strony github . Jest to przydatne, jeśli lubisz aplikacje wiersza poleceń i jesteś zainteresowany wprowadzaniem szybkich zmian w nazwach plików. (Moja aplikacja jest podobna do polecenia „bulkrename” znajdującego się w ranger ).

Jim Shaddix
źródło
1
Chociaż zachęcamy do umieszczania linków do zewnętrznych zasobów, odradzamy udzielanie odpowiedzi zawierających tylko łącza, ponieważ stają się one bezużyteczne po wygaśnięciu łącza. Zaktualizuj swoją odpowiedź, tak aby zawierała odpowiedź na pytanie :)
IT Delinquent
Absolutnie. Zmienię swój post. To mój pierwszy wkład, więc doceniam wskazówki!
Jim Shaddix
0

Ten kod zadziała

Funkcja przyjmuje dokładnie dwa argumenty f_patth jako ścieżkę do zmiany nazwy pliku i nowa_nazwa jako nową nazwę pliku.

import glob2
import os


def rename(f_path, new_name):
    filelist = glob2.glob(f_path + "*.ma")
    count = 0
    for file in filelist:
        print("File Count : ", count)
        filename = os.path.split(file)
        print(filename)
        new_filename = f_path + new_name + str(count + 1) + ".ma"
        os.rename(f_path+filename[1], new_filename)
        print(new_filename)
        count = count + 1
murthy annavajhula
źródło