I have a main directory that contains multiple folders. I wanna loop through these sub folders, check for each sub folder if it contains more than (e.g. 10 files) keep the 10 files and move the rest to a new directory, otherwise delete the subfolder.
This is how my directory looks like:
Each sub directory contains around 100 files, I wanna loop through these sub directories, do a check first, keep 10 files, and move the rest to a new directory.
I would presume that this can be done with the help of pathlib or os but I need a help in writing the script.
I think the code will be something like the following:
for directory in os.listdir('path'):
for file in os.listdir(os.path.join('path', directory)):
if(....){
# keep 10 files and move the rest to a new directory
} else {
# delete the subdir
}
I suggest to use shutil library for moving and removing files and directories, below is an example for moving a file from a path to another path:
import shutil
original = r'original_path_where_the_file_is_currently_stored\file_name.file_extension'
target = r'target_path_where_the_file_will_be_moved\file_name.file_extension'
shutil.move(original,target)
And below is an example for removing a directory including all it's content:
import shutil
dirPath = '/path_to_the_dir/name_of_dir/'
shutil.rmtree(dirPath)
We use the two snippets above to create the final code:
import shutil
import os
new_dir_path = "path_to_the_new_dir/new_dir_name"
for directory in os.listdir('path'):
for index, file in enumerate(file_list := os.listdir(path_dir := os.path.join('path', directory))):
if(len(file_list) >= 10):
# keep 10 files and move the rest to a new directory
if(index > 9):
shutil.move(os.path.join(path_dir,file),os.path.join(new_dir_path,file))
else:
# delete the subdir
shutil.rmtree(path_dir)
Related
I am trying to move the first file in a folder into another folder using python. I am using shutil in order to do this.
I know that the following will move the whole S folder into the D folder. but how do I choose only the first file within the folder?
S = '/Users/kitchensink/Desktop/Sfolder'
D = '/Users/kitchensink/Desktop/Dfolder'
shutil.move(S, D)
print("moved")
You can use glob to find the files in a folder. For example if you want to have a list with all files in SFolder you can do this:
import glob
s_files = glob.glob('/Users/kitchensink/Desktop/Sfolder/*')
To get the first file, simply take the first element from s_files.
After this you can still use shutil to do the actual moving.
What I have is an initial directory with a file inside D:\BBS\file.x and multiple .txt files in the work directory D:\
What I am trying to do is to copy the folder BBS with its content and incrementing it's name by number, then copy/move each existing .txt file to the newly created directory to make it \BBS1, \BBS2, ..., BBSn (depends on number of the txt).
Visual example of the Before and After:
Initial view of the \WorkFolder
Desired view of the \WorkFolder
Right now I have reached only creating of a new directory and moving txt in it but all at once, not as I would like to. Here's my code:
from pathlib import Path
from shutil import copy
import shutil
import os
wkDir = Path.cwd()
src = wkDir.joinpath('BBS')
count = 0
for content in src.iterdir():
addname = src.name.split('_')[0]
out_folder = wkDir.joinpath(f'!{addname}')
out_folder.mkdir(exist_ok=True)
out_path = out_folder.joinpath(content.name)
copy(content, out_path)
files = os.listdir(wkDir)
for f in files:
if f.endswith(".txt"):
shutil.move(f, out_folder)
I kindly request for assistance with incrementing and copying files one by one to the newly created directory for each as mentioned.
Not much skills with python in general. Python3 OS Windows
Thanks in advance
Now, I understand what you want to accomplish. I think you can do it quite easily by only iterating over the text files and for each one you copy the BBS folder. After that you move the file you are currently at. In order to get the folder_num, you may be able to just access the file name's characters at the particular indexes (e.g. f[4:6]) if the name is always of the pattern TextXX.txt. If the prefix "Text" may vary, it is more stable to use regular expressions like in the following sample.
Also, the function shutil.copytree copies a directory with its children.
import re
import shutil
from pathlib import Path
wkDir = Path.cwd()
src = wkDir.joinpath('BBS')
for f in os.listdir(wkDir):
if f.endswith(".txt"):
folder_num = re.findall(r"\d+", f)[0]
target = wkDir.joinpath(f"{src.name}{folder_num}")
# copy BBS
shutil.copytree(src, target)
# move .txt file
shutil.move(f, target)
I wrote a short script, where I want to moves all .CR2 (in the next step I want to choose between the first the first 2 or 6 files) Files to a Folder, which has been created before as raw_input.
import os
from os import path
import shutil
import itertools
proname = raw_input("Please Name the Productfolder: ")
path = "/Volumes/01_Produktfotos/_2020-01-JANUAR/"
os.mkdir(proname)
os.chdir(proname)
os.makedirs('_final')
os.makedirs('_images')
os.makedirs('_psd')
sourcepath = '/Volumes/01_Produktfotos/_2020-01-JANUAR/03.01/'
sourcefiles = os.listdir(sourcepath)
destinationpath = '/Volumes/01_Produktfotos/_2020-01-JANUAR/03.01/%proname/_images/'
for file in sourcefiles:
if file.endswith('.CR2'):
shutil.move(os.path.join(sourcepath,file), os.path.join(destinationpath,file))
At the moment, the script creates the user specific Folder (proname) and generates the subfolder _images, _final & _psd inside of it.
My Problem is that it doesn't moves the files from the top folder in the user created folder.
The Perfect Result would be if
I can choose a Productfolder Name
It creates inside of the Folder the subfolder _images, _final & _psd
I can choose if I want the first 2-6 .CR2 Files inside of the Subfolder _images of the created Productfolder
The Script is running till there are no .CR2 Files left
Any help or hints are welcome (:
Thx in advance
As in doc, dst is a directory, not a file.
shutil.move(src, dst) Recursively move a file or directory (src) to
another location (dst). If the destination is an existing directory, then src is moved inside that directory. If the destination already exists but is not a directory, it may be overwritten depending on os.rename() semantics.
# Before:
shutil.move(os.path.join(sourcepath,file), os.path.join(destinationpath,file))
# After:
shutil.move(os.path.join(sourcepath,file), destinationpath))
will work.
The following change solved the problem, with moving .CR2 Files in the specific proname Folder:
destinationpath = os.path.join('/Volumes/01_Produktfotos/_2020-01-JANUAR/03.01/', proname, '_images')
Now I'm in the next step, where not all .CR2 files should be moved. Just the first 2 or 6 files.
So I've started down the path again of trying to automate something. My end game is to combine the data within Excel files containing the Clean Up in the file name and combine the data from a tab within these files named LOV. So basically it had to go into a folder with folders which have folders again that have 2 files, one file has the words Clean Up in the naming and is a .xlsx file. Which I need to only read those files and and pull the data from the tab called LOV into one large file. --- So that's my end goal. Which I just started and I am no where near, but now you know the end game.
Currently I'm stuck just getting a list of Folder names in the Master folder so I at least know it's getting there lol.
import os
import glob
import pandas as pd
# assigns directory location to PCC Folder
os.chdir('V:/PCC Clean Up Project 2017/_DCS Data SWAT Project/PCC Files
Complete Ready to Submit/Brake System Parts')
FolderList = glob.glob('')
print(FolderList)
Any help is appreciated, thanks guys!
EDITED
Firstly Its hard to understand your question. But from what I understand you need to iterate over folders and subfolders, you can do that with
for root, dirs, files in os.walk(source): #Give your path in source
for file in filenames:
if file.endswith((".xlxs")): # You can check for any file extension
filename = os.path.join(subdir,file)
dirname = subdir.split(os.path.sep)[-1] # gets the directory name
print(dirname)
If you only want the list of folders in your current directory, you can use os.path. Here is how it works:
import os
directory = "V:/PCC Clean Up Project 2017/_DCS Data SWAT Project/PCC Files
Complete Ready to Submit/Brake System Parts"
childDirectories = next(os.walk(directory))[1]
This will give you a list of all folders in your current directory.
Read more about os.walk here.
You can then go into one of the child directories by using os.chdir:
os.chdir(childDirectories[i])
I'm having trouble making folders that I create go where I want them to go. For each file in a given folder, I want to create a new folder, then put that file in the new folder. My problem is that the new folders I create are being put in the parent directory, not the one I want. My example:
def createFolder():
dir_name = 'C:\\Users\\Adrian\\Entertainment\\Coding\\Test Folder'
files = os.listdir(dir_name)
for i in files:
os.mkdir(i)
Let's say that my files in that directory are Hello.txt and Goodbye.txt. When I run the script, it makes new folders for these files, but puts them one level above, in 'C:\Users\Adrian\Entertainment\Coding.
How do I make it so they are created in the same place as the files, AKA 'C:\Users\Adrian\Entertainment\Coding\Test Folder'?
import os, shutil
for i in files:
os.mkdir(os.path.join(dir_name , i.split(".")[0]))
shutil.copy(os.path.join(dir_name , i), os.path.join(dir_name , i.split(".")[0]))
os.listdir(dir_name) lists only the names of the files, not full paths to the files. To get a path to the file, join it with dir_name:
os.mkdir(os.path.join(dir_name, i))