Copy files in Python - python-3.x

I want to copy files with a specific file extention from one directory and put in another directory. I tried searching and found code the same as im doing however it doesnt appear to do anything, any help would be great.
import shutil
import os
source = "/tmp/folder1/"
destination = "/tmp/newfolder/"
for files in source:
if files.endswith(".txt"):
shutil.move(files,destination)

I think the problem is your for-loop. You are actually looping over the string "tmp/folder1/" instead of looping over the the files in the folder. What your for-loop does is going through the string letter by letter (t, m, p etc.).
What you want is looping over a list of files in the source folder. How that works is described here: How do I list all files of a directory?.
Going fro there you can run through the filenames, testing for their extension and moving them just as you showed.

Your "for file in source" pick one character after another one from your string "source" (the for doesn't know that source is a path, for him it is just a basic str object).
You have to use os.listdir :
import shutil
import os
source = "source/"
destination = "dest/"
for files in os.listdir(source): #list all files and directories
if os.path.isfile(os.path.join(source, files)): #is this a file
if files.endswith(".txt"):
shutil.move(os.path.join(source, files),destination) #move the file
os.path.join is used to join a directory and a filename (to have a complete path).

Related

Python 3 - Copy files if they do not exist in destination folder

I am attempting to move a couple thousand pdfs from one file location to another. The source folder contains multiple subfolders and I am combining just the pdfs (technical drawings) into one folder to simplify searching for the rest of my team.
The main goal is to only copy over files that do not already exist in the destination folder. I have tried a couple different options, most recently what is shown below, and in all cases, every file is copied every time. Prior to today, any time I attempted a bulk file move, I would received errors if the file existed in the destination folder but I no longer do.
I have verified that some of the files exist in both locations but are still being copied. Is there something I am missing or can modify to correct?
Thanks for the assistance.
import os.path
import shutil
source_folder = os.path.abspath(r'\\source\file\location')
dest_folder = os.path.abspath(r'\\dest\folder\location')
for folder, subfolders, files in os.walk(source_folder):
for file in files:
path_file=os.path.join(folder, file)
if os.path.exists(file) in os.walk(dest_folder):
print(file+" exists.")
if not os.path.exists(file) in os.walk(dest_folder):
print(file+' does not exist.')
shutil.copy2(path_file, dest_folder)
os.path.exists returns a Boolean value. os.walk creates a generator which produces triples of the form (dirpath, dirnames, filenames). So, that first conditional will never be true.
Also, even if that conditional were correct, your second conditional has a redundancy since it's merely the negation of the first. You could replace it with else.
What you want is something like
if file in os.listdir(dest_folder):
...
else:
...

How to match a list to file names, then move matched files to new directory in Python?

I have a folder of 90,000 PDF documents with sequential numeric titles (e.g. 02.100294.PDF). I have a list of around 70,000 article titles drawn from this folder. I want to build a Python program that matches titles from the list to titles in the folder and then moves the matched files to a new folder.
For example, say I have the following files in "FOLDER";
1.100.PDF
1.200.PDF
1.300.PDF
1.400.PDF
Then, I have a list with of the following titles
1.200.PDF
1.400.PDF
I want a program that matches the two document titles from the list (1.200 and 1.400) to the documents in FOLDER, and then move these two files to "NEW_FOLDER".
Any idea how to do this in Python?
Thank you!
EDIT: This is the code I currently have. The source directory is 'scr', and 'dst' is the new destination. "Conden_art" is the list of files I want to move. I am trying to see if the file in 'scr' matches a name listed in 'conden_art'. If it does, I want to move it to 'dst'. Right now, the code is finding no matches and is only printing 'done'. This issue is different from just moving files because I need to match file names to a list, and then move them.
import shutil
import os
for file in scr:
if filename in conden_art:
shutil.copy(scr, dst)
else:
print('done')
SOLVED!
Here is the code I used that ended up working. Thanks for all of your help!
import shutil
import os
import pandas as pd
scr = filepath-1
dst = filepath-2
files = os.listdir(scr)
for f in files:
if f in conden_art:
shutil.move(scr + '\\' + f, dst)
Here's a way to do it -
from os import listdir
from os.path import isfile, join
import shutil
files = [f for f in listdir(src) if isfile(join(src, f))] # this is your list of files at the source path
for i in Conden_art:
if i in files:
shutil.move(i,dst+i) # moving the files in conden_art to dst/
src and dst here are your paths for source and destination. Make sure you are at the src path before running the for loop. Otherwise, python will be unable to find the file.
Rather than looping through the files in the source directory it would be quicker to loop through the filenames you already have. You can use os.path.exists() to check if a file is available to be moved.
from os import path
import shutil
for filename in conden_art:
src_fp, dst_fp = path.join(src, filename), path.join(dst, filename)
if path.exists(filepath):
shutil.move(src_fp, dst_fp)
print(f'{src_fp} moved to {dst}')
else:
print(f'{src_fp} does not exist')

Get all files in a matching subdirectory name

I have this piece of code from another project:
import pathlib
p = pathlib.Path(root)
for img_file in p.rglob("*.jpg"):
#Do something for each image file
It finds all jpg files in the whole directory and its subfolders and acts upon them.
I have a directory that contains 100+ 'main' folders with each folder having some combination of 2 subfolders - lets call them 'FolderA' and 'FolderB'. The main folders can have one, both or none of these subfolders.
I want to run a piece of code against all the pdf files contained within the 'FolderB' subdirectories, but ignore all files in the main folders and 'FolderA' folders.
Can someone help me manipulate the above code to allow me to continue?
Many thanks!
You can modify the pattern to just search for what you want:
from pathlib import Path
p = Path("root")
for file in p.rglob("*FolderB/*.pdf"):
# Do something with file
pass

use glob module to get certain files with python?

The following is a piece of the code:
files = glob.iglob(studentDir + '/**/*.py',recursive=True)
for file in files:
shutil.copy(file, newDir)
The thing is: I plan to get all the files with extension .py and also all the files whose names contain "write". Is there anything I can do to change my code? Many thanks for your time and attention.
If you want that recursive option, you could use :
patterns = ['/**/*write*','/**/*.py']
for p in patterns:
files = glob.iglob(studentDir + p, recursive=True)
for file in files:
shutil.copy(file, newDir)
If the wanted files are in the same directory you could simply use :
certainfiles = [glob.glob(e) for e in ['*.py', '*write*']]
for file in certainfiles:
shutil.copy(file, newDir)
I would suggest the use of pathlib which has been available from version 3.4. It makes many things considerably easier.
In this case '**' stands for 'descend the entire folder'.
'*.py' has its usual meaning.
path is an object but you can recover its string representation using the str function to get just the file name.
When you want the entire path name, use path.absolute and get the str of that.
Don't worry, you'll get used to it. :) If you look at the other goodies in pathlib you'll see it's worth it.
from pathlib import Path
studentDir = <something>
newDir = <something else>
for path in Path(studentDir).glob('**/*.py'):
if 'write' in str(path):
shutil.copy(str(path.absolute()), newDir)

List files of specific file type and directories

I'm attempting to create a script that looks into a specific directory and then lists all the files of my chosen types in addition to all folders within the original location.
I have managed the first part of listing all the files of the chosen types, however am encountering issues listing the folders.
The code I have is:
import datetime, os
now = datetime.datetime.now()
myFolder = 'F:\\'
textFile = 'myTextFile.txt'
outToFile = open(textFile, mode='w', encoding='utf-8')
filmDir = os.listdir(path=myFolder)
for file in filmDir:
if file.endswith(('avi','mp4','mkv','pdf')):
outToFile.write(os.path.splitext(file)[0] + '\n')
if os.path.isdir(file):
outToFile.write(os.path.splitext(file)[0] + '\n')
outToFile.close()
It is successfully listing all avi/mp4/mkv/pdf files, however isn't ever going into the if os.path.isdir(file): even though there are multiple folders in my F: directory.
Any help would be greatly appreciated. Even if it is suggesting a more effective/efficient method entirely that does the job.
Solution found thanks to Son of a Beach
if os.path.isdir(file):
changed to
if os.path.isdir(os.path.join(myFolder, file)):
os.listdir returns the names of the files, not the fully-qualified paths to the files.
You should use a fully qualified path name in os.path.isdir() (unless you've already told Python where to look).
Eg, instead of using if os.path.isdir(file): you could use:
if os.path.isdir(os.path.join(myFolder, file)):

Resources