Loop over multiple folders from list with glob.glob - python

How can I loop over a defined list of folders and all of the individual files inside each of those folders?
I'm trying to have it copy all the months in each year folder. But when I run it nothing happens..
import shutil
import glob
P4_destdir = ('Z:/Source P4')
yearlist = ['2014','2015','2016']
for year in yearlist:
for file in glob.glob(r'{0}/*.csv'.format(yearlist)):
print (file)
shutil.copy2(file,P4_destdir)

I think the problem might be that you require a / in you source path:
import shutil
import glob
P4_destdir = ('Z:/Source P4/')
yearlist = ['2014','2015','2016'] # assuming these files are in the same directory as your code.
for year in yearlist:
for file in glob.glob(r'{0}/*.csv'.format(yearlist)):
print (file)
shutil.copy2(file,P4_destdir)
Another thing that might be a problem is if the destination file does not yet exist. You can create it using os.mkdir:
import os
dest = os.path.isdir('Z:/Source P4/') # Tests if file exists
if not dest:
os.mkdir('Z:/Source P4/')

Related

How to move files based on their names with python? [duplicate]

This question already has answers here:
Moving all files from one directory to another using Python
(11 answers)
Closed 6 months ago.
I have a folder with a lot of tutorial links, so I wanted to create a script that reads the file name and for instance, if the file has in its name the word "VBA" or "Excel" it would create the folder Excel and send to it. The same would happen with files containing the word "python".
The code is running, but nothing happens and the files still in the same directory. Does anyone have an idea of what I'm doing wrong?
Here is what I have in the folder, all files are links to youtube tutorials or websites:
Please see my code below:
import os
import shutil
os.chdir(r"C:\Users\RMBORGE\Desktop\Useful stuff")
path = r"C:\Users\RMBORGE\Desktop\Useful stuff\Excel"
for f in os.listdir():
if "vba" in f:
shutil.move(os.chdir,path)
Try this
import os
import shutil
path_to_files = 'some path'
files = os.listdir(path_to_files)
for f in files:
if 'Excel' in f:
created_folder = os.path.join(path_to_files, 'Excel')
filepath = os.path.join(path_to_files, f)
os.makedirs(created_folder, exist_ok=True)
shutil.move(filepath, created_folder)
NB: You can add more if statements for different keywords like Excel
Use pathlib mkdir for creating the folders. Prepare the folders/keywords you want sort in the list 'folders'. And then what is important is skipping the folders because os.listdir() gives you the folders aswell (and there is an error if you want to move a folder into itself)
import os
import shutil
import pathlib
folders = ["vba", "Excel"]
path = "/home/vojta/Desktop/THESIS/"
for f in os.listdir():
if not os.path.isdir(os.path.join(path, f)): # skip folders
for fol in folders:
if fol in f:
pathlib.Path(os.path.join(path, fol)).mkdir(parents=True, exist_ok=True)
fol_path = os.path.join(path, fol)
shutil.move(os.path.join(path, f), os.path.join(fol_path, f))

How to move files with similar filename into new folder in Python

I have a list of files like this in the images folder.
and How can I create a new folder if there are multiple files with a similar name and move those similar files to that folder?
I am new to python.
Here is my expectation:
Try this:
import glob
from pathlib import Path
for fn in Path("Images").glob("*"):
file_base_name = "_".join(fn.stem.split("_")[:-1])
file_count = len(glob.glob1("Images", f"{file_base_name}*"))
if file_count > 1 or Path(file_base_name).is_dir():
outdir = Path("Images") / file_base_name
outdir.mkdir(exist_ok=True)
fn.rename(outdir / fn.name)
Input:
Output:
Please ignore file names extension. I create those just to test my code
In this case you don't even need re:
from pathlib import Path
for fn in Path("Images").glob("*.jpg"):
outdir = Path("Images") / "_".join(fn.stem.split("_")[:-1])
outdir.mkdir(exist_ok=True)
fn.rename(outdir / fn.name)
What's going on here?
Pathlib is how you want to think of paths if you can. It combines most of the os.path apis. Specifically:
glob gets us all the files matching the glob in the path
mkdir makes the directory (only if it doesn't exist)
rename moves the file there
I am unable to test since I don't have your files. My suggestion would be to comment out the mkdir command and the shutil.move command and replace them with print statements to see what commands would be generated before letting it run for real. But I think it should work.
import pathlib
import os
import re
from itertools import groupby
import shutil
source_dir = 'Images'
files = [os.path.basename(f) for f in pathlib.Path(source_dir).glob('*.jpg')]
def keyfunc(file):
m = re.match('^(.*?)_\d+.jpg$', file)
return m[1]
matched_files = [file for file in files if re.search(r'_\d+.jpg$', file)]
matched_files.sort()
for k, g in groupby(matched_files, keyfunc):
new_dir = os.path.join(source_dir, k)
if not os.path.exists(new_dir):
os.mkdir(new_dir)
for file in g:
shutil.move(os.path.join(source_dir, file), new_dir)

How to read particular text files out-of multiple files in a sub directories in python

I have a one folder, within it contains 5 sub-folders.
Each sub folder contains some 'x.txt','y.txt' and 'z.txt' files and it repeats in every sub-folders
Now I need to read and print only 'y.txt' file from all sub-folders.
My problem is I'm unable to read and print 'y.txt' files. Can you tell me how solve this problem.
Below is my code which I have written for reading y.txt file
import os, sys
import pandas as pd
file_path = ('/Users/Naga/Desktop/Python/Data')
for root, dirs, files in os.walk(file_path):
for name in files:
print(os.path.join(root, name))
pd.read_csv('TextInformation.txt',delimiter=";", names = ['Name', 'Value'])
error :File TextInformation.txt does not exist: 'TextInformation.txt'
You could also try the following approach to fetch all y.txt files from your subdirectories:
import glob
import pandas as pd
# get all y.txt files from all subdirectories
all_files = glob.glob('/Users/Naga/Desktop/Python/Data/*/y.txt')
for file in all_files:
data_from_this_file = pd.read_csv(file, sep=" ", names = ['Name', 'Value'])
# do something with the data
Subsequently, you can apply your code to all the files within the list all_files. The great thing with glob is that you can use wilcards (*). Using them you don't need the names of the subdirectories (you can even use it within the filename, e.g. *y.txt). Also see the documentation on glob.
Your issue is forgot adding the parent path of 'y.txt' file. I suggest this code for you, hope it help.
import os
pth = '/Users/Naga/Desktop/Python/Data'
list_sub = os.listdir(pth)
filename = 'TextInformation.txt'
for sub in list_sub:
TextInfo = open('{}/{}/{}'.format(pth, sub, filename), 'r').read()
print(TextInfo)
I got you a little code. you can personalize it anyway you like but the code works for you.
import os
for dirPath,foldersInDir,fileName in os.walk(path_to_main_folder):
if fileName is not []:
for file in fileName:
if file.endswith('y.txt'):
loc = os.sep.join([dirPath,file])
y_txt = open(loc)
y = y_txt.read()
print(y)
But keep in mind that {path_to_main} is the path that has the subfolders.

How to move from one directory to another and delete only '.html' files in python?

I attended an interview and they asked me to write a script to move from one directory to another and delete only the .html files.
Now I tried to do this at first using os.remove() . Following is the code:
def rm_files():
import os
from os import path
folder='J:\\Test\\'
for files in os.listdir(folder):
file_path=path.join(folder,files)
os.remove(file_path)
The problem I am facing here is that I cannot figure out how to delete only .html files in my directory
Then I tried using glob. Following is the code:
def rm_files1():
import os
import glob
files=glob.glob('J:\\Test\\*.html')
for f in files:
os.remove(f)
Using glob I can delete the .html files but still I cannot figure out how to implement the logic of moving from one directory to another.
And along with that can someone please help me figure out how to delete a specific file type using os.remove() ?
Thank you.
Either of these methods should work. For the first way, you could just string.endswith(suffix) like so:
def rm_files():
import os
from os import path
folder='J:\\Test\\'
for files in os.listdir(folder):
file_path=path.join(folder,files)
if file_path.endswith(".html"):
os.remove(file_path)
Or if you prefer glob, moving directories is fairly straightforward: os.chdir(path) like this:
def rm_files1():
import os
os.chdir('J:\\Test')
import glob
files=glob.glob('J:\\Test\\*.html')
for f in files:
os.remove(f)
Though it seems unnecessary since glob is taking an absolute path anyway.
Your problem can be described in the following steps.
move to specific directory. This can be done using os.chdir()
grab list of all *.html files. Use glob.glob('*.html')
remove the files. use os.remove()
Putting it all together:
import os
import glob
import sys
def remove_html_files(path_name):
# move to desired path, if it exists
if os.path.exists(path_name):
os.chdir(path_name)
else:
print('invalid path')
sys.exit(1)
# grab list of all html files in current directory
file_list = glob.glob('*.html')
#delete files
for f in file_list:
os.remove(f)
#output messaage
print('deleted '+ str(len(file_list))+' files in folder' + path_name)
# call the function
remove_html_files(path_name)
To remove all html files in a directory with os.remove() you can do like this using endswith() function
import sys
import os
from os import listdir
directory = "J:\\Test\\"
test = os.listdir( directory )
for item in test:
if item.endswith(".html"):
os.remove( os.path.join( directory, item ) )

Python - I zip some folders with subfolders but it zips twice.

I have written a script. It finds the current path and changes the path and zips. Then I want that it just find the zip file copy it to another directory and at the end removes the content of the folder. But it zips once and zips again the whole folders and zip-file. The intial situation is as in Figure 1.
The script is like this:
import os
import zipfile
import shutil
import glob
Pfad = os.getcwd()
newPfad = 'D'+ Pfad[1:]
Zip_name=os.path.basename(os.path.normpath(Pfad))
shutil.make_archive(Zip_name, 'zip', Pfad)
if not os.path.exists(newPfad):
os.makedirs(newPfad)
dest_dir=newPfad
files = glob.iglob(os.path.join(Pfad, "*.zip"))
for file in files:
if os.path.isfile(file):
shutil.copy2(file, dest_dir)
shutil.rmtree(Pfad)
And finally the result is illustrated in the following figure.
The batch file is just for running the python script.
How can I get the following desired situation?
The issue is that zip file is created prior to listing the directory contents, therefore empty zip file is added to. Create archive in the parent directory and then move it. Moving a file or directory is cheap and atomic.
import os
import shutil
cwd = os.path.abspath(os.path.curdir)
zip_target = os.path.join(cwd, os.path.basename(cwd)) + '.zip'
zip_source = shutil.make_archive(cwd, 'zip')
os.rename(zip_source, zip_target)

Categories