Saving Multiple Local/Offline Files to Target Folder with OS Module - python

I am trying to move all files that are in Just source_path to the target_path.
Here is the code:
import os
target_path = 'C:/Users/Justi/source/repos/GUI Developmentv3/Test 02' + '\\'
source_path ='C:/Users/Justi/source/repos/GUI Developmentv3/' + '\\'
for path, dir, files in os.walk(source_path):
if files:
for file in files:
if not os.path.isfile(target_path + file):
os.rename(path + '\\' + file, target_path + file)
However, this also moves other files that are in the sub-directory folders of the source folder into the target folder.
May I check how I could change the code to only move files at the exact directory of source_path without affecting files in source_path's sub-dictionary? Thank you in advance.

I think the problem is the usage of os.walk, because it walks the whole tree. See the docs:
Generate the file names in a directory tree by walking the tree either top-down or bottom-up.
You are only interested in the contents of a particular folder, so os.listdir is more suitable:
Return a list containing the names of the entries in the directory given by path.
The following code will iterate over the files in the source dir, and move only the files into the target dir.
import os
import shutil
source = "source"
target = "target"
for f in os.listdir(source):
print(f"Found {f}")
if os.path.isfile(os.path.join(source, f)):
print(f"{f} is a file, will move it to target folder")
shutil.move(os.path.join(source, f), os.path.join(target, f))

Related

how can I move files from subfolder/sub-subfolder recursively ? [python]

I have problems solving a task. Below you can see my code. I want to work with sub-sub-folders too but my code only moves the sub-folders. How can I do this recursively that it moves all folders in main folder?
path = (r"C:\Users\Desktop\testfolder")
os.chdir(path)
all_files = list(os.listdir())
outputs = os.getcwd()
for files in all_files:
try:
inputs = glob.glob(files + "\\*")
for a in inputs:
shutil.move(a, outputs)
except:
pass
for files in os.listdir("."):
dir_folder = files[:32]
if not os.path.isdir(dir_folder):
try:
os.mkdir(dir_folder)
except:
pass
Here is the new code, that will maintain the folder structure in the output folder as it was in the input folder
from pathlib import Path
import shutil
import os
for path, dir_folder, files in os.walk('./test_folder'):
for file in files:
full_path = os.path.join(path,file)
## Create the path to the subfolder
sub_folder_path = '/'.join(path.split('/')[2:])
# Create output path by joining subfolder path and output directory
output_path = os.path.join(outputs, sub_folder_path)
# Create the output path directory structure if it does not exists, ignore if it does
Path(output_path).mkdir(parents=True, exist_ok=True)
# Move file
shutil.move(full_path, output_path)
You can use os.walk to recursively visit each folder and sub folder and then move all the files in that folder.
import shutil
import os
for path, dir_folder, files in os.walk(input_folder):
for file in files:
full_path = os.path.join(path,file)
move_path = os.path.join(output_path,file)
print(move_path)
shutil.move(full_path, move_path)
print(file)
Where output_path is the path to the folder you move to move the files to.
This will not create the same folder structure in output folder, just move all the files there, do you also want to maintain structure in output folder? If so, I can edit my answer to reflect that

python unzip all files to parent directory

How can I extract all the .zip files in a certain directory to its parent directory?
I tried:
import zipfile
parent_directory = '../input'
directory = '../input/zip'
for f in os.listdir(directory):
with zipfile.ZipFile(os.path.join(directory,f), "r") as z:
z.extractall(parent_directory)
However the unzipped files are not saved in '..input/zip', they are saved in nested folders
This might be a bit exaggerated.
After files are unzipped, I run this to:
move the original .zip file up one directory level. (to avoid /src_filename' already exists error)
move all files from all subdirectories into the zip parent directory.
move the original .zip file back into the parent directory.
import os
import shutil
src = r'C:\Users\Owner\Desktop\PythonZip\PyUnzip01\child_dir\unzip_test2'
dest = r'C:\Users\Owner\Desktop\PythonZip\PyUnzip01\child_dir'
pdir = '../PyUnzip01'
os.replace(r"C:\Users\Owner\Desktop\PythonZip\PyUnzip01\child_dir\unzip_test2.zip", r"C:\Users\Owner\Desktop\PythonZip\PyUnzip01\unzip_test2.zip")
for root, subdirs, files in os.walk(src):
for file in files:
path = os.path.join(root, file)
shutil.move(path, dest)
os.replace(r"C:\Users\Owner\Desktop\PythonZip\PyUnzip01\unzip_test2.zip", r"C:\Users\Owner\Desktop\PythonZip\PyUnzip01\child_dir\unzip_test2.zip")

python: collect files with one extention from all sub-dir

I am trying to collect all files with all sub-directories and move to another directory
Code used
#collects all mp3 files from folders to a new folder
import os
from pathlib import Path
import shutil
#run once
path = os.getcwd()
os.mkdir("empetrishki")
empetrishki = path + "/empetrishki" #destination dir
print(path)
print(empetrishki)
#recursive collection
for root, dirs, files in os.walk(path, topdown=True, onerror=None, followlinks=True):
for name in files:
filePath = Path(name)
if filePath.suffix.lower() == ".mp3":
print(filePath)
os.path.join
filePath.rename(empetrishki.joinpath(filePath))
I have trouble with the last line of moving files: filePath.rename() nor shutil.move nor joinpath() have worked for me. Maybe that's because I am trying to change the element in the tuple - the output from os.walk
Similar code works with os.scandir but this would collect files only in the current directory
How can I fix that, thanks!
If you use pathlib.Path(name) that doesn't mean that something exists called name. Hence, you do need to be careful that you have a full path, or relative path, and you need to make sure to resolve those. In particular I am noting that you don't change your working directory and have a line like this:
filePath = Path(name)
This means that while you may be walking down the directory, your working directory may not be changing. You should make your path from the root and the name, it is also a good idea to resolve so that the full path is known.
filePath = Path(root).joinpath(name).resolve()
You can also place the Path(root) outside the inner loop as well. Now you have an absolute path from '/home/' to the filename. Hence, you should be able to rename with .rename(), like:
filePath.rename(x.parent.joinpath(newname))
#Or to another directory
filePath.rename(other_dir.joinpath(newname))
All together:
from pathlib import os, Path
empetrishki = Path.cwd().joinpath("empetrishki").resolve()
for root, dirs, files in os.walk(path, topdown=True, onerror=None, followlinks=True):
root = Path(root).resolve()
for name in files:
file = root.joinpath(name)
if file.suffix.lower() == ".mp3":
file.rename(empetrishki.joinpath(file.name))
for root, dirs, files in os.walk(path, topdown=True, onerror=None, followlinks=True):
if root == empetrishki:
continue # skip the destination dir
for name in files:
basename, extension = os.path.splitext(name)
if extension.lower() == ".mp3":
oldpath = os.path.join(root, name)
newpath = os.path.join(empetrishki, name)
print(oldpath)
shutil.move(oldpath, newpath)
This is what I suggest. Your code is running on the current directory, and the file is at the path os.path.join(root, name) and you need to provide such path to your move function.
Besides, I would also suggest to use os.path.splitext for extracting the file extension. More pythonic. And also you might want to skip scanning your target directory.

How can I change multiple filenames in different subdirectories in python?

I am working with Python3 and am trying to change the names of files in multiple subdirectories to match the folder name. My directory looks like this:
path: C:\Users\Me\Project
In the path, I have the following folders: alldata, folderA, folderB, folderC
FolderA, folderB, and folderC, each contain a file called data.csv
I want to add the letter name of the folder (e.g., A, B, C) to the file (e.g., dataA.csv) inside the folder and then move all these renamed files to "alldata"
I really appreciate the help!
This one might be a little hardcoded, but is probably more understandable for people who are just starting out in Python:
import os
import shutil
# Enter the 'Project' folder
os.chdir('C:\\Users\\Me\\Project')
# Filter for folders that contain the word 'folder'
folders = [folder for folder in os.listdir() if 'folder' in folder]
for folder in folders:
# Get the last letter of every folder
suffix = folder[-1]
# Build source and destination path for the csv files
source = folder + '\\data.csv'
dest = 'alldata\\data' + suffix + '.csv'
shutil.move(source, dest)
The 'os' module in python gives you access to functions that deal with folders and files. For example, there are functions in the os module to move, copy, rename, delete folders and files. Try this for example:
import os
basePath = "C:\\Users\\Me\\Project\\"
# Rename and move the data.csv file in folderA to dataA.csv in the alldata folder
os.rename(basePath + "folderA\\data.csv", basePath + "alldata\\dataA.csv")
# Rename and move the data.csv file in folderB to dataB.csv in the alldata folder
os.rename(basePath + "folderB\\data.csv", basePath + "alldata\\dataB.csv")
# Rename and move the data.csv file in folderC to dataC.csv in the alldata folder
os.rename(basePath + "folderC\\data.csv", basePath + "alldata\\dataC.csv")
# Make sure that they moved as intended
filesInAllDataFolder = os.listdir(basePath + "alldata\\")
print(filesInAllDataFolder)
The os module is super handy and I guarantee you'll use it a lot, so play with it!
This works for me:
import os
def scan_dir(folder):
for name in os.listdir(folder):
path = os.path.join(folder, name)
if os.path.isfile(path):
if 'data' in path:
dir_name = path.split('/')[-2]
new_name_path = path[:-3]+dir_name+'.csv'
new_name_path = new_name_path.split('/')
new_name_path[-2] = 'alldata'
new_name_path = "/".join(new_name_path)
os.rename(path, new_name_path)
else:
scan_dir(path)
directory = 'C:\Users\Me\Project'
scan_dir(directory)

How to copy files of a certain type in python

I have a folder (with other subfolders) from which i would like to copy only the .js files to another existing folder (this also has subfolders with the same folder structure as the first one, except this one has only the folders, so no file)
How can i do that with python? I tried shutil.copytree but it fails because some folders already exists.
use os.path.splitext or glob.iglob
glob.iglob(pathname)
Return an iterator which yields the same values as glob() without
actually storing them all simultaneously.
I propose a solution with os.path.splitext, walking with os.walk. I make use of os.path.relpath to find relative path in the duplicate tree.
source_dir is your source uppermost source folder, dest_dir your uppermost destination folder.
import os, shutil, glob
source_dir = "F:\CS\PyA"
dest_dir = "F:\CS\PyB"
for root, dirnames, filenames in os.walk(source_dir):
for file in filenames:
(shortname, extension) = os.path.splitext(file)
if extension == ".txt" :
shutil.copy2(os.path.join(root,file), os.path.join(dest_dir,
os.path.relpath(os.path.join(root,file),source_dir)))
from glob import glob
from shutil import copy
import os
def copyJS(src, dst):
listing = glob(src + '/*')
for f in listing:
if os.path.isdir(f):
lastToken = f.split('/')[-1]
copyJS(src+'/' + lastToken, dst+ '/' + lastToken)
elif f[-3:] == '.js':
copy(f, dst)

Categories