TangerCity
TangerCity

Reputation: 845

How to rename unzipped files in Python?

I have the following structure:

Folder1
      ZZ-20201201-XX.zip
Folder2
      XX-20201201-XX.zip
      XX-20201202-XX.zip
Folder3
      YY-20201201-XX.zip
      YY-20201202-XX.zip

With below code Im creating a counterpart of Folder1, Folder2 and Folder3 and directly unzipping the zipped files inside those 3 folders. So I receive this:

Folder1
      ZZ-.txt

Folder2
      XX-.txt
     
Folder3
      YY.txt

As you can see the files lose the date once they get unzipped so if a folder contains 2 zipped files they will get the same name and thus the files will be rewritten. Now I want to add the date of the zipped files to the files once they are unzipped. How can I do this?

import fnmatch

pattern = '*.zip'
for root, dirs, files in os.walk(my_files): 
    for filename in fnmatch.filter(files, pattern): 
        path = os.path.join(root, filename)
        date_zipped_file = re.search('-(.\d+)-', filename).group(1) #<-- this is the date of the zipped files and I want this to be included in the name of the unzipped files once they get unzipped.

        # Store the new directory so that it can be recreated
        new_dir = os.path.normpath(os.path.join(os.path.relpath(path, start=my_files), ".."))

        # Join your target directory with newly created directory
        new = os.path.join(counter_part, new_dir)

        # Create those folders, works even with nested folders
        if (not os.path.exists(new)):
            os.makedirs(new)

        zipfile.ZipFile(path).extractall(new) 

my desired outcome:

Folder1
      ZZ-20201201.txt
Folder2
      XX-20201201.txt
      XX-20201202.txt
Folder3
      YY-20201201.txt
      XX-20201202.txt

Upvotes: 1

Views: 141

Answers (1)

spcial
spcial

Reputation: 1569

You could just rename the files after you have unzipped each folder. Something like this:

#get all files in that unzipped folder
files = os.listdir(path)

#rename all files in that dir
for file in files:
    filesplit = os.path.splitext(os.path.basename(file))
    os.rename(os.path.join(path, file), os.path.join(path, filesplit[0]+'_'+date_zipped_file+filesplit[1]))

but that also renames files which might actually have already a date in the name. So you would also need to integrate a check if the file was already renamed. Either by maintaining a list with file names or a simple regex which looks for 8 digit string between a '_' and a '.', e.g. text_20201207.txt.

#get all files in that unzipped folder
    files = os.listdir(path)
    
    #rename all files in that dir
    for file in files:
        filesplit = os.path.splitext(os.path.basename(file))
        if not re.search(r'_\d{8}.', file):
            os.rename(os.path.join(path, file), os.path.join(path, filesplit[0]+'_'+date_zipped_file+filesplit[1]))

your final solution would then look something like this:

import fnmatch

pattern = '*.zip'
for root, dirs, files in os.walk(my_files): 
    for filename in fnmatch.filter(files, pattern): 
        path = os.path.join(root, filename)
        date_zipped_file = re.search('-(.\d+)-', filename).group(1) #<-- this is the date of the zipped files and I want this to be included in the name of the unzipped files once they get unzipped.

        # Store the new directory so that it can be recreated
        new_dir = os.path.normpath(os.path.join(os.path.relpath(path, start=my_files), ".."))

        # Join your target directory with newly created directory
        new = os.path.join(counter_part, new_dir)

        # Create those folders, works even with nested folders
        if (not os.path.exists(new)):
            os.makedirs(new)

        zipfile.ZipFile(path).extractall(new) 

        #get all files in that unzipped folder
        files = os.listdir(new)
    
        #rename all files in that dir
        for file in files:
            filesplit = os.path.splitext(os.path.basename(file))
            if not re.search(r'_\d{8}.', file):
                os.rename(os.path.join(new, file), os.path.join(new, filesplit[0]+'_'+date_zipped_file+filesplit[1]))

Upvotes: 1

Related Questions