Get all files in a matching subdirectory name - python-3.x

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

Related

copying files from one folder to another folder based on the file names in python 3

In Python 3.7, I want to write a scrip that
creates folders based on a list
iterates through a list (elements represent different "runs")
searches for .txt files in predifined directories derived from certain operations
copies certain .txt files to the previously created folders
I managed to do that via following script:
from shutil import copy
import os
import glob
# define folders and batches
folders = ['folder_ce', 'folder_se']
runs = ['A001', 'A002', 'A003']
# make folders
for f in folders:
os.mkdir(f)
# iterate through batches,
# extract files for every operation,
# and copy them to target folder
for r in runs:
# operation 1
ce = glob.glob(f'{r}/{r}/several/more/folders/{r}*.txt')
for c in ce:
copy(c, 'folder_ce')
# operation 2
se = glob.glob(f'{r}/{r}/several/other/folders/{r}*.txt')
for s in se:
copy(s, 'folder_se')
In the predifined directories there are several .txt files
one file with the format A001.txt (where the "A001"-part is derived from the list "runs" specified above)
plus sometimes several files with the format A001.20200624.1354.56.txt
If a file with the format A001.txt is there, I only want to copy this one to the target directory.
If the format A001.txt is not available, I want to copy all files with the longer format (e.g. A001.20200624.1354.56.txt).
After the comment of #adamkwm, I tried
if f'{b}/{b}/pcs.target/data/xmanager/CEPA_Station/Verwaltung_CEPA_44S4/{b}.txt' in cepa:
copy(f'{b}/{b}/pcs.target/data/xmanager/CEPA_Station/Verwaltung_CEPA_44S4/{b}.txt', 'c_py_1')
else:
for c in cepa:
copy(c, 'c_py_1')
but that still copies both files (A001.txt and A001.20200624.1354.56.txt), which I understand. I think the trick is to first check in ce, which is a list, if the {r}.txt format is present and if it is, only copy that one. If not, copy all files. However, I don't seem to get the logic right or use the wrong modules or methods, it seems.
After searching for answers, i didn't find one resolving this specific case.
Can you help me with a solution for this "selective copying" of the files?
Thanks!

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:
...

Is there a way to give multiple file locations for renaming files?

I want a program to rename subtitles file as same as the movie file, which are located in different folders and sub-folders.
What I have done:
Imported os, re, and shutil modules.
Made a for loop to iterate through a directory and return files/folders inside of a parent folder.
for foldername, subfoldername, filename in os.walk('E:\Movies'):
This loop will iterate through the E:\Movies folder and assume a list of sub folders and files.
To check whether file is a subtitle file, inside of for loop,
if filename.endswith('(.srt|.idx|.sub)'):
How do i give multiple paths and new names in the single second argument?
os.rename(filename,'')
Why do you want to give multiple paths and new names in the second argument?
The Code you shared does the following :
Loop through the directory tree.
For each filename in directory :
If file is subtitle file :
Rename file to movie file present some directory
In the last step you are not renaming all the files at once. You are doing them one at a time.
os.rename(src,dest)
Accepts two arguments only, the src filename and dest filename.
So for your case you will have to loop again through all the files in the directory, match the name of subtitle file with movie file, and then rename the subtitle file.
Try Something Like :
for foldername,subfoldername,filename in os.walk('E:\Movies'):
if filename.endswith('(.srt|.idx|.sub)'):
for folder2,subfolder2,moviename in os.walk('E:\Movies'):
# We don't want to match the file with itself
if(moviename != filename):
# You would have to think of your matching logic here
# How would you know if that subtitle is of that particular movie
# eg. if subtitle is of form 'a_good_movie.srt' you can split on '_' and check if all words are present in movie name
Edit
After the clarifications in the comments, it seems you want to implement the following :
Loop through all Folders in Directory:
For each Folder in directory, rename all subtitle_files to the Folder name
You can do this in Python 3 like this :
for folder in next(os.walk(directory))[1]:
for filename in next(os.walk(directory+folder))[2]:
if(filename.endswith(('.srt','.idx','.sub'))):
os.rename(filename,directory);
os.walk() returns a generator function. You can access the value of os.walk() generator as such in python 3 :
next(os.walk('C:\startdir'))[0] # returns 'C:\startdir'
next(os.walk('C:\startdir'))[1] # returns list of directories in 'C:\startdir'
next(os.walk('C:\startdir'))[2] # returns list of files in 'C:\startdir'
For python 2 you can call os.walk().next()[] with same return values

Importing a whole folder of python files

In the current python program I'm working on, I need to access a lot of stored data. I store it in the form of a bunch of dictionaries, each in their own file. Each file has a single command: giveArchive(). So to access one of the files, I use:
import fileName
return fileName.giveArchive()
And this has worked well so far, but as the number of files I need grows, I want to streamline this a little bit. I'd like to store all of these files in the same folder, and that folder in the same directory as my main file. Is there some way I can import every file in a folder? And if I do, how can I use 'giveArchive()' from specific files in it?
You can do something like:
from folder.subfolder.deepersubfolder import filename
return filename.giveArchive()
this assumes folder can be accessed from the directory your script is running in

Copy files in Python

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).

Resources