Renaming and Zipping Files Python - FileNotFoundError - python

Just getting back into Python and am trying to build a script that will match file names, rename, zip them, and then ultimately build a control file off them (this I haven't written yet). It works on the files placed in the directory, but at the end I get the error: FileNotFoundError: [WinError 2] The system cannot find the file specified: 'A20190331.txt' -> 'B20190530.txt'. Is it rerunning my txt_files for loop in the beginning after renaming? Code is probably not optimal at this point.
import os
import zipfile
try:
import zlib
compression = zipfile.ZIP_DEFLATED
except:
compression = zipfile.ZIP_STORED
path = 'mypath'
txt_files = []
for root, dirs, files in os.walk(path):
for file in files:
txt_files.append(file)
def create_zip(data_dt):
for files in txt_files:
if '.py' in files:
continue
elif 'A' in files:
file_name = 'A' + data_dt + '.txt'
name_full_path = path +'\\'+ file_name
os.rename(files, file_name)
zf = zipfile.ZipFile('A' + data_dt+ '.zip', mode='w')
zf.write(name_full_path, file_name, compress_type=compression)
zf.close()
elif 'B' or 'C' in files:
file_name = 'B' + data_dt + '.txt'
name_full_path = path +'\\'+ file_name
os.rename(files, file_name)
zf = zipfile.ZipFile('B' + data_dt +'.zip', mode='w')
zf.write(name_full_path, file_name, compress_type=compression)
zf.close()
else:
break
create_zip('20190530')

Christopher.
I see your problem immediately:
txt_files = []
for root, dirs, files in os.walk(path):
for file in files:
txt_files.append(file)
I believe you want to keep the path:
for root, dirs, files in os.walk(path):
for file in files:
txt_files.append(os.path.join(os.path.get_cwd(), file))
Let os.path handle the path for you -- it is portable across platforms and less error prone.
hth

i did some modification, can you try this please , but using your way, the code will overwrite the files.
so try this script, and tell me if you want to overwrite or just rename and zip
def create_zipe(data_dt):
for files in txt_files:
if '.py' in files:
continue
elif 'ASS' in files:
file_name = 'A' + data_dt + '.txt'
name_full_path = path +'/'+ file_name
os.rename(files, file_name)
zf = zipfile.ZipFile('A' + data_dt+ '.zip', mode='w')
zf.write(name_full_path, file_name, compress_type=compression)
zf.close()
elif 'C' in files or 'B' in files:
file_name = 'B' + data_dt + '.txt'
print(file_name)
name_full_path = path +'/'+ file_name
print(name_full_path)
os.rename(files, file_name)
zf = zipfile.ZipFile('B' + data_dt+ '.zip', mode='w')
zf.write(name_full_path, file_name, compress_type=compression)
zf.close()

Related

How to rename files after being copied based on creation time?

After copying files from a user provided source and destination, the files need to be renamed based on the creation time. The files have multiple extension types that need to be preserved while being renamed and a record original filenames. The issue arises when attempting to rename the file after it has been copied to the destination. All attempted solutions creates an exception in callback. What's the best approach here?
def filter_copy(self):
current_dir = self.Source.get()
destination_dir = self.Destination.get()
extensions = (['.avi', '.mpg'])
os.chdir(current_dir)
for root, dir, files in os.walk('.'):
for file in files:
if os.path.splitext(file)[1] in extensions:
src = os.path.join(root, file)
time.sleep(0.1)
logging.info("Copying the file %s..." % file)
print("Copying the file %s..." % file)
try:
with open('OriginalFilesReceipt.txt', 'w') as f:
f.write(file)
except FileNotFoundError:
logging.info("The directory does not exist to create to generate a receipt")
shutil.copy(src, destination_dir)
for names in os.listdir('.'):
t = os.path.getmtime(names)
v = datetime.datetime.fromtimestamp(t)
x = v.strftime('%Y%m%d-%H%M%S')
os.rename(names, x)
Found a solution based on the work from yzhong52 here: https://gist.github.com/tvdsluijs/1640613a32416b1197fc36b45e7b4999
The main error that was being received should have been obvious. The working directory wasn't the destination directory. The solution for the original question:
os.chdir(destination_dir)
for names in os.listdir('.'):
#split into filename and extension
filename, extension = os.path.splitext(names)
if (extension in extensions):
create_time = os.path.getctime(names)
format_time = datetime.datetime.fromtimestamp(create_time)
format_time_string = format_time.strftime("%Y-%m-%d %H.%M.%S")
newfile = format_time_string + extension
#if other file with same timestamp
if(newfile in newfilesDictionary.keys()):
index = newfilesDictionary[newfile] + 1
newfilesDictionary[newfile] = index
newfile = format_time_string + '-' + str(index) + extension
else:
newfilesDictionary[newfile] = 0
os.rename(names, newfile)
num_files = num_files + 1
print(names.rjust(35) + ' => ' + newfile.ljust(35))

zip file is zipping to default project dir folder rather than file dir

my code is :
def zip_file(path, zip_file_name ,root):
ziph = zipfile.ZipFile(zip_file_name, 'w', zipfile.ZIP_DEFLATED)
ziph.write(path, arcname= os.path.join(root, os.path.splitext(zip_file_name)[0]))
#os.remove(path)
ziph.close()
def zip_dir(dir_to_zip):
for root, dirs, files in os.walk(dir_to_zip):
for curr_file in files:
fullFilePath = os.path.join(root, curr_file)
if not curr_file.endswith('.zip'):
zip_file(fullFilePath, "{}.zip".format(fullFilePath), root)
if __name__ == '__main__':
zip_dir('C:\\Users\\My_namne\\Desktop\\TEST')
I want it to zip the file to the original folder, but it zips to work dir of my project all of the files. How to change the dir of output archive? now it zip to my working directory and the zip the entire root to path
The first argument to zipfile.ZipFile should be the complete path to the archive you are creating. Make the change in zip_dir
def zip_dir(dir_to_zip):
for root, dirs, files in os.walk(dir_to_zip):
for curr_file in files:
fpath = os.path.join(root, curr_file)
zip_file(fpath, "{}.zip".format(fpath),root)
This will create an archive for each file in its directory. The archive will only contain the file itself, not the file's entire path.
import os, zipfile
def zip_file(filepath, zipfilepath ,curr_file):
with zipfile.ZipFile(zipfilepath, 'w', zipfile.ZIP_DEFLATED) as ziph:
ziph.write(filepath, arcname=curr_file)
def zip_dir(dir_to_zip):
for root, dirs, files in os.walk(dir_to_zip):
for curr_file in files:
if not curr_file.endswith('.zip'):
filepath = os.path.join(root, curr_file)
zipfilepath = "{}.zip".format(filepath)
zip_file(filepath, zipfilepath, curr_file)
def zip_file(filename):
zip_filename = os.path.splitext(filename)[0] + '.zip'
f = zipfile.ZipFile(zip_filename, 'w')
f.write(filename, os.path.basename(filename), zipfile.ZIP_DEFLATED)
f.close()
return zip_filename
def zip_dir(dir_to_zip):
for root, dirs, files in os.walk(dir_to_zip):
for curr_file in files:
fullFilePath = os.path.join(root, curr_file)
if not curr_file.endswith('.zip'):
zip_file(fullFilePath)
this works

python How do I import multiple .txt files in a folder to add characters to each .txt file?

There are text files of various names in the folder 'a'. I want to read all of these text files and add the letter 'b' to each text file. What should I do?
cwd = os.getcwd()
input_dir = os.path.join(cwd, "my .txt files dir")
sorts = sorted(glob(input_dir), key = lambda x:(len(x) , x))
for f in sorts :
f = open(input_dir, 'a')
data = "add text"
f.write(data)
f.close()
Append data to file:
- first: get all file in folder a.
- second: find extension with .txt.
- third: open it and do something('append', or 'rewrite').
Demo:
import os
# your .txt files dir
path = 'a'
# append data what you want
appendData = 'b'
fileNames = list(os.walk(path))[0][2]
fileNames.sort(key=len)
fileNums = len(fileNames)
# your dst file extension
fileExt = '.txt'
# # Extract extension from filename
# fileExt = os.path.splitext(fileNames[0])[1]
for fileName in fileNames:
if fileName.endswith(fileExt):
fileFullPath = os.path.join(path, fileName)
with open(fileFullPath, 'a') as f:
f.write(appendData)
Like the others said, this is an easy question that could easily be find on google. Anyway here's how to do it:
from os import listdir
from os.path import isfile, isdir, join
files = [file for file in listdir("files") if isfile(join("files", file))]
directories = [directory for directory in listdir("files") if isdir(join("files", directory))]
print(files)
for file_name in files:
try:
file = open("files/" + file_name, "a")
file.write("b")
file.close()
except IOError as err:
print("Could not open file because : ", err)
Replace "file" with the directory where your files are or the path to that directory like "directory0/directory1/directory_with_files"
Avoid to open files with
f = open(input_dir, 'a')
f.close()
Instead
with open(input_dir, 'a') as inputFile:
Do something
Also what you want is
import os
import glob # We will use this module to open only .txt files
path = 'your/path'
for filename in glob.glob(os.path.join(path, '*.txt'))
with open(filename, 'a') as inputFile:
inputFile.write('b')

How would I exclude directories from os.listdir results?

I'm making a script that will encode files within a directory using b64/b16 and I'm using os.listdir to do so, but it also lists directories which causes problems since now it's trying to encode directories as if it were a file.
How would I be able to exclude directories from os.listdir results?
import os
import sys
import base64
import codecs
import time
import string
import glob
#C:\\Users\\Fedora\\Desktop\\Win 10
path = "C:\\Users\\Fedora\\Desktop\\Win 10"
dirs = os.listdir(path)
files = []
filecount = 0
fileprogress = 0
for file in dirs:
files.append(file)
filecount = filecount + 1
for x in files:
os.system("cls")
fileprogress = fileprogress + 1
print("File " + str(fileprogress) + "/" + str(filecount))
print("Encrypting " + x + "...")
inputfile = open(path + "\\" + x, "rb")
data = inputfile.read()
inputfile.close()
data = base64.b16encode(data)
data = base64.b64encode(data)
data = base64.b16encode(data)
data = base64.b64encode(data)
data = base64.b16encode(data)
outputfile = open(path + "\\" + x + ".crypt", "wb")
outputfile.write(data)
outputfile.close()
use filter
filepath = "C:\\Users\\Fedora\\Desktop\\Win 10"
dirs = os.listdir(path)
files = filter(lambda x:os.path.isfile(os.path.join(filepath, x)), dirs)
or list comprehension with os.path.isfile()
filepath = "C:\\Users\\Fedora\\Desktop\\Win 10"
dirs = os.listdir(path)
files = [x for x in dirs if os.path.isfile(os.path.join(filepath, x))]
You can use os.path.isdir function to check if the current file is a directory.
Also, it is much better to use string formatting operations instead of string concatenation: not
print("File " + str(fileprogress) + "/" + str(filecount))
but
print("File {}/{}".format(fileprogress, filecount))
Such code is much easier to understand and modify.
Instead of using os.listdir() your can use os.walk which will return separate list for files and directories
python-oswalk-example
import os
path = "C:\\Users\\Fedora\\Desktop\\Win 10"
for (path, dirs, files) in os.walk(path):
print path
print dirs
print files
pythoncentral os-walk
#Import the os module, for the os.walk function
import os
#Set the directory you want to start from
path = "C:\\Users\\Fedora\\Desktop\\Win 10"
for dirName, subdirList, fileList in os.walk(path):
print('Found directory: %s' % dirName)
for fname in fileList:
print('\t%s' % fname)

How to create an extension for a file without extension in Python

I have a folder with a list of files without extensions, I need to rename or create an extension to each file ".text"
This is my code, but there is a small bug, the second time I run the code the files renamed again with a long name ,, for example
The file name : XXA
after first run : XXA.text
second : XXAXXA.text.text
import os
def renamefiles():
filelist = os.listdir(r"D:\")
print(filelist)
os.chdir(r"D:\")
path = os.getcwd()
for filename in filelist:
print("Old Name - "+filename)
(prefix, sep, sffix) = filename.rpartition(".")
newfile = prefix + filename + '.text'
os.rename(filename, newfile)
print("New Name - "+newfile)
os.chdir(path)
rename_files()
Where you have
newfile = prefix + '.text'
You can have
if not file_name.contains(".text"):
newfile = prefix + file_name + '.text'
Note where you have newfile = prefix + file_name + '.text', I changed it to newfile = prefix + '.text'. If you think about it, you don't need filename when you have already extracted the actual file name into prefix.
for file in os.listdir(os.curdir):
name, ext = os.path.splitext(file)
os.rename(file, name + ".text")
Don't do the partitioning that way, use os.path.splitext:
file_name, extension = os.path.splitext(filename)
if not extension:
newfile = file_name + '.text'
os.rename(filename, newfile)
If the file has no extension splitext returns '' which is Falsy. The file extension can then be changed.
import os
def renamefiles():
filelist = os.listdir(r"D:\")
print(filelist)
os.chdir(r"D:\")
path = os.getcwd()
for filename in filelist:
print("Old Name - "+filename)
(prefix, sep, sffix) = filename.rpartition(".")
newfile = prefix + filename + '.text'
if not filename.endswith(".text"):
os.rename(filename, newfile)
print("New Name - "+newfile)
os.chdir(path)
renamefiles()
You need to check if the filename ends with .text, and skip those

Categories

Resources