Selective Copy:
Write a program that walks through a folder tree and searches for
files with a certain file extension (such as .pdf or .jpg). Copy these
files from whatever location they are into a new folder.
I keep getting a traceback error as seen in this screenshot.
I do not know what I am doing wrong.
This is the code I have:
import os, shutil, sys
def selective_copy(src_folder: str = None, ext: str = None, dest_folder: str = None) -> None:
if src_folder is None:
raise AttributeError('src_folder must be given.')
if ext is None:
raise AttributeError('.jpg')
if dest_folder is None:
raise AttributeError('dest_folder must be given.')
src_folder = os.path.abspath(src_folder)
os.chdir(src_folder)
os.mkdir(dest_folder)
# Walk through a folder tree
for foldername, subfolders, filenames in os.walk("./"):
print("Looking in folder: %s..." % foldername)
# Find files with a specific extension
for filename in filenames:
if filename.endswith('.jpg'):
# Copy files to a new folder
print("Copying file: %s..." % filename)
shutil.copy(filename, dest_folder)
print("Done.")
def main():
selective_copy('../', '.jpg', 'new_folder')
if __name__ == '__main__':
main()
Instead of os.mkdir(), I would suggest looking at os.makedirs() (documentation). It has a parameter that I believe you'll find useful for this situation.
Related
I want to move files from one directory to another from a .txt file containing the names of the files to be moved, the script must first browse the directory and if it finds the file it moves it to the new directory. Where to start? I've managed to do this for a file list but I'd like to do it directly via the .txt file without rewriting the names of the files to be moved
import shutil, os
files = ['file1.txt', 'file2.txt', 'file3.txt', 'file4.txt']
for file in files:
shutil.move(file, 'destination_directory')
As I know, U cant move your files with .txt
Just move your file_path
You can use my code below.
I have double checked and it work on my side.
Sorry for my poor English Skill :)
import os
import shutil
from pathlib import Path
def create_directory(dir_name: str):
"""To create directory before create files: txt, csv..."""
system_path = os.getcwd()
dir_path = os.path.join(system_path, dir_name)
try:
os.makedirs(dir_path, exist_ok=True)
except OSError as error:
print("Directory '%s' can not be created" % dir_name)
return dir_path
def create_files(dir_path: str, file_name: str):
"""Function for creating files"""
file_path = dir_path + fr"\{file_name}"
with open(file_path, "w") as open_file:
if Path(file_path).is_file():
print(f'File: {file_name} created successfully')
else:
print(f'File: {file_name} does not exist')
open_file.close() # Need to close.
return file_path
def main():
# Step 1: Creating file1.txt, file2.txt, file3.txt, file4.txt
file_one = create_files(create_directory("file1_dir"), 'file1.txt')
file_two = create_files(create_directory("file2_dir"), 'file2.txt')
file_three = create_files(create_directory("file3_dir"), 'file3.txt')
file_four = create_files(create_directory("file4_dir"), 'file4.txt')
# Step 2: Creating destination_directory:
destination_dir = create_directory('destination_directory')
files = [file_one, file_two, file_three, file_four]
# Step 3: Moving Your Files:
for file in files:
shutil.move(file, destination_dir)
if __name__ == "__main__":
main()
I want to copy folders and files from a source directory to another destination directory. Each directory contains subfolders and many files already.
So far, I try the following code, inspired by a post in Stackoverflow:
import os
import shutil
root_src_dir = r'C:\....'
root_dst_dir = r'C:\....'
for src_dir, dirs, files in os.walk(root_src_dir):
dst_dir = src_dir.replace(root_src_dir, root_dst_dir, 1)
if not os.path.exists(dst_dir):
os.makedirs(dst_dir)
for file_ in files:
src_file = os.path.join(src_dir, file_)
dst_file = os.path.join(dst_dir, file_)
if os.path.exists(dst_file):
# in case of the src and dst are the same file
if os.path.samefile(src_file, dst_file):
continue
os.remove(dst_file)
shutil.copy2(src_file, dst_dir)
This code equates destination directory with source directory for identical folder and file names. This can replace the most recent folders and files in the destination, which is a disaster, while I want to keep the newest ones stay in both directories, when they had identical folder and file names.
This is a program i wrote. It is a interactive one also with move and delete function along with copy. And filters data based on the extension.
import os
import shutil
from os.path import join
from time import perf_counter
print('Written By : SaGaR')
print('Applies operation on all the files with specified ext. to the destination path specified:')
scandir=input('Enter the path to scan(absolute or relative path):')
print(f'You entered :{scandir}')
choice = input('Enter operation to perform(move|copy|delete|list):').lower()
EXCLUDE=['Android','DCIM', 'documents', 'WhatsApp', 'MIUI','bluetooth'] #exclude some system folder on android . Add your one also.
if choice == 'copy' or choice =='move':
dest=input('Enter the destination path(absolute or relative path):')
print(f'You entered :{dest}')
EXCLUDE.append(dest)
DATA_TYPES=input('Enter Data types to filter(comma-seprated)(ex.- jpg,txt): ').split(',')
files2=[]
print('*'*5,'FINDING FILES')
for root, dirs, files in os.walk(scandir):
for file in files:
for typ in DATA_TYPES:
if file.endswith(typ):
a = join(root,file)
print(root, end='')
print('-->',file)
files2.append(a)
for directory in EXCLUDE:
if directory in dirs:
dirs.remove(directory)
def copy_move_files():
start=perf_counter()
print('-'*5, f'Trying To {choice.capitalize} Files')
if not os.path.isdir(dest):
print(f'{dest} does not exists')
print(f'Creating {dest} directory')
os.mkdir(dest)
else:
print(f'{dest} exists')
for file in files2:
fpath=os.path.join(dest,os.path.split(file)[-1])
try:
if not os.path.exists(fpath):
if choice=='move':
shutil.move(file,dest)
print(f'{file.split("/")[-1]} Moved Successfully')
if choice=='copy':
shutil.copy(file,dest)
print(f'{file.split("/")[-1]} Copied Successfully')
else:
print(f'{file.split("/")[-1]} Already in destination folder')
except shutil.SameFileError:
print(f'{file.split("/")[-1].strip()} Already Exists in the destination directory. Add the Destination directory to EXCLUDE ')
end = perf_counter() - start
print(f'Operation took {end} second(s)')
def delete_files():
print('-'*5, 'Trying To Delete Files')
for file in files2:
os.remove(file)
print(f'{file} deleted')
if choice == 'copy' or choice=='move':
copy_move_files()
elif choice == 'delete':
delete_files()
else:
print('No valid or "list" option detected\nOnly listing Files')
print('Exiting the program Now')
This is a solution using shutil.copytree and a my_copy function.
In my_copy there is an if statement that check which is the newest file.
import os
import shutil
def my_copy(src, dst):
print(src)
print(dst)
if not os.path.exists(dst):
shutil.copy2(src,dst)
else:
if os.path.getmtime(src) > os.path.getmtime(dst):
shutil.copy2(src,dst)
return True
def rec_copy():
root_src_dir = r'C:\...'
root_dst_dir = r'C:\...'
try:
if not os.path.exists(root_dst_dir):
print(os.path.exists(root_dst_dir))
os.makedirs(root_dst_dir)
print(os.path.exists(root_dst_dir))
shutil.copytree(root_src_dir , root_dst_dir, copy_function=my_copy, dirs_exist_ok=True)
except Exception as err:
print(err)
For my class I have to write code that will receive a pathname and then display the file contents if its a file or display each file and its contents if a directory is the pathname.
I wrote the following code, which works fine when I test it with my own local directory. But when I run the checks on my class portal it returns an error "No such file or directory".
Can anyone help me see what's wrong with my code?
import os
def openFyle(filename):
openFile = open(filename)
return openFile.read()
def displayFiles(filename):
if os.path.isdir(filename):
os.chdir(filename)
print("Directory name:", os.getcwd())
dirLyst = os.listdir(filename)
for file in dirLyst:
if os.path.isfile(file):
return print("File name:", file, openFyle(file))
elif os.path.exists(file) and os.path.isdir(file):
os.chdir(file)
displayFiles(os.getcwd())
else:
print("File name:", filename, openFyle(filename))
def main():
#while True:
filename = input("Enter a pathname: ")
displayFiles(filename)
if __name__ == "__main__":
main()
Using the os module:
import os
def print_all_file_contents(directory):
for root, dirs, files in os.walk(directory):
for file in files:
print(open(os.path.join(root, file)).read())
if __name__ == "__main__":
print_all_file_contents(input("Enter a directory:"))
What I would guess is, one of the tests they're using on your function is to send an invalid path. In your function, you only cover two cases: either its a path or its a file and you print out the file name with its contents. What if you cant find that file? That else should be an elif that does the os.path.isfile, and then an else in case its an invalid path.
This should fix it.
def displayFiles(filename):
if os.path.isdir(filename):
os.chdir(filename)
print("Directory name:", os.getcwd())
dirLyst = os.listdir(filename)
for file in dirLyst:
if os.path.isfile(file):
return print("File name:", file, openFyle(file))
elif os.path.exists(file) and os.path.isdir(file):
os.chdir(file)
displayFiles(os.getcwd())
elif os.path.isfile(filename):
print("File name:", filename, openFyle(filename))
else:
print("Invalid input")
. I think the portal runs automated tests that pass it path names.
Sure, but that doesn't prevent it from giving you invalid input data, such as non-str or Path-like objects or non existing locations
Also, rather than using chdir, create the absolute path as you go using path.join
def displayFiles(filename):
if filename and os.path.exists(filename):
if os.path.isdir(filename):
print("Directory name:", filename)
for file in os.listdir(filename):
child = os.path.join(filename,file)
displayFiles(child)
else:
print("File name:", filename, openFyle(filename))
else:
print("Invalid input")
Almost any time you're working with file system paths in Python, I recommend pathlib, because it's awesome. It doesn't make a huge difference this this case, but getting used to using it will make things much easier when you need to, say, join multiple paths together.
from pathlib import Path
def display_file(path):
print(f'File: {path}\n')
print(path.read_text())
print('\n\n')
if __name__ == '__main__':
path = Path(input('Enter a pathname: '))
if path.is_dir():
for item in path.iterdir():
# This avoids attempting to print hidden files, which may exist
# depending on the OS / filesystem.
if item.is_file() and not item.name.startswith('.'):
display_file(item)
elif path.is_file():
display_file(path)
The code only tries to print contents if the path is in fact a file or a directory; it displays nothing if passed an invalid or nonexistant path.
I am modifying a wizard in Kodi and I would like the wizard to delete all folders contained within the "addons" directory without deleting my wizard.
The directory of the folder will be using the "special://" function built into Kodi. I would like to delete everything inside of "special://home/addons" except for the folder named "plugin.video.spartan0.12.0"
I know that python needs to use "xbmc.translatePath" function to recognize the folder path, but I don't know how to delete everything in the folder without deleting "plugin.video.spartan0.12.0"
Any help would be appreciated.
Here is what I currently have
import os
dirPath = "C:\Users\Authorized User\AppData\Roaming\Kodi\addons"
fileList = os.listdir(dirPath)
for fileName in fileList:
os.remove(dirPath+"/"+fileName)
This is probably overkill (and a little sloppy), but it worked for me:
import os
import shutil
#----------------------------------------------------------------------
def remove(path):
"""
Remove the file or directory
"""
if os.path.isdir(path):
try:
shutil.rmtree(path)
except OSError:
print "Unable to remove folder: %s" % path
else:
try:
if os.path.exists(path):
os.remove(path)
except OSError:
print "Unable to remove file: %s" % path
#----------------------------------------------------------------------
def cleanup(dirpath, folder_to_exclude):
for root, dirs, files in os.walk(dirpath, topdown=True):
for file_ in files:
full_path = os.path.join(root, file_)
if folder_to_exclude not in full_path:
print 'removing -> ' + full_path
remove(full_path)
for folder in dirs:
full_path = os.path.join(root, folder)
if folder_to_exclude not in full_path:
remove(full_path)
if __name__ == '__main__':
cleanup(r'c\path\to\addons', 'plugin.video.spartan0.12.0')
I need help editing the following script which Zips the contents of a directory. My end goal is creating a script that will look at C:\Test (which will have multiple directories inside) and make a new zip file with the contents of each directory in C:\Test. The tricky part is that I need the path to be C:\ even though the directories true paths are C:\Test. Is this possible or am I dreaming ?
Thanks
import zipfile, os
def makeArchive(fileList, archive):
try:
a = zipfile.ZipFile(archive, 'w', zipfile.ZIP_DEFLATED)
for f in fileList:
print "archiving file %s" % (f)
a.write(f)
a.close()
return True
except: return False
def dirEntries(dir_name, subdir, *args):
fileList = []
for file in os.listdir(dir_name):
dirfile = os.path.join(dir_name, file)
if os.path.isfile(dirfile):
if not args:
fileList.append(dirfile)
else:
if os.path.splitext(dirfile)[1][1:] in args:
fileList.append(dirfile)
# recursively access file names in subdirectories
elif os.path.isdir(dirfile) and subdir:
print "Accessing directory:", dirfile
fileList.extend(dirEntries(dirfile, subdir, *args))
return fileList
if __name__ == '__main__':
folder = r'C:\test'
zipname = r'C:\test\test.zip'
makeArchive(dirEntries(folder, True), zipname)
You can change the path of the file inside the archive as follows:
a.write(PATH_ON_FILESYSTEM,
DESIRED_PATH_IN_ARCHIVE
)