FileNotFoundError when attempting to move files into a temp directory - python

I am attempting to move files inside of a subdirectory into a temp folder. Here is my code:
with tempfile.TemporaryDirectory() as tempDirectory:
for root, dirs, files in os.walk(fileDestination, topdown=True):
for file in files:
shutil.move(file, tempDirectory)
When I look at my debugger I can see the values of the file variable holding the files I want to move. But nothing moves and I am then given the error FileNotFoundError that references the file I want to move. When I look into my file explorer I can see that the file did not move.

Figured it out on my own. So even though file variable was holding the filename it was not holding the entire path to the file. The below code works:
for subdir, dirs, files in os.walk(fileDestination, topdown=True):
for file in files:
fileName = os.path.join(fileDestination+"\\"+file)
print(fileName)
shutil.move(fileName, tempDirectory)

Related

Python script to move specific filetypes from the all directories to one folder

I'm trying to write a python script to move all music files from my whole pc to one spcific folder.
They are scattered everywhere and I want to get them all in one place, so I don't want to copy but completely move them.
I was already able to make a list of all the files with this script:
import os
targetfiles = []
extensions = (".mp3", ".wav", ".flac")
for root, dirs, files in os.walk('/'):
for file in files:
if file.endswith(extensions):
targetfiles.append(os.path.join(root, file))
print(targetfiles)
This prints out a nice list of all the files but I'm stuck to now move them.
I did many diffent tries with different code and this was one of them:
import os
import shutil
targetfiles = []
extensions = (".mp3", ".wav", ".flac")
for root, dirs, files in os.walk('/'):
for file in files:
if file.endswith(extensions):
targetfiles.append(os.path.join(root, file))
new_path = 'C:/Users/Nicolaas/Music/All' + file
shutil.move(targetfiles, new_path)
But everything I try gives me an error:
TypeError: rename: src should be string, bytes or os.PathLike, not list
I think I've met my limit gathering this all as I'm only starting at Python but I would be very grateful if anyone could point me in the right direction!
You are trying to move a list of files to a new location, but the shutil.move function expects a single file as the first argument. To move all the files in the targetfiles list to the new location, you have to use a loop to move each file individually.
for file in targetfiles:
shutil.move(file, new_path)
Also if needed add a trailing slash to the new path 'C:/Users/Nicolaas/Music/All/'
On a sidenote are you sure that moving all files with those extentions is a good idea? I would suggest copying them or having a backup.
Edit:
You can use an if statement to exclude certain folders from being searched.
for root, dirs, files in os.walk('/'):
if any(folder in root for folder in excluded_folders):
continue
for file in files:
if file.endswith(extensions):
targetfiles.append(os.path.join(root, file))
Where excluded_folder is a list of the unwanted folders like: excluded_folders = ['Program Files', 'Windows']
I would suggest using glob for matching:
import glob
def match(extension, root_dir):
return glob.glob(f'**\\*.{extension}', root_dir=root_dir, recursive=True)
root_dirs = ['C:\\Path\\to\\Albums', 'C:\\Path\\to\\dir\\with\\music\\files']
excluded_folders = ['Bieber', 'Eminem']
extensions = ("mp3", "wav", "flac")
targetfiles = [f'{root_dir}\\{file_name}' for root_dir in root_dirs for extension in extensions for file_name in match(extension, root_dir) if not any(excluded_folder in file_name for excluded_folder in excluded_folders)]
Then you can move these files to new_path

Moving all .txt files in a directory to a new folder with os.walk()?

import os
import shutil
folder = 'c:\\Users\\myname\\documents'
for folderNames, subfolders, filenames in os.walk(folder):
for file in filenames:
if file.endswith('.txt'):
shutil.copy(?????, 'c:\\Users\\myname\\documents\\putfileshere\\' + file)
This was simple to do for all .txt files in a folder by using os.listdir but I'm having trouble with this because in oswalk I don't know how to get the full filepath of the file that ends in .txt since it could be in however many subfolders
Not sure If I'm using the correct terminology of directory, but to be more clear I want to move all .txt files to the new folder even if it's 1,2,3 subfolders deep into the documents folder.
To get the full path, you have to combine the root and filename parts. The root part points to the full path of the enumerated file names.
for root, _, filenames in os.walk(folder):
for filename in filenames:
if filename.endswith('.txt'):
file_path = os.path.join(root, filename)
shutil.copy(file_path, ...)
You could also use glob.glob(pathname)

Reading all files that start with a certain string in a directory

Say I have a directory.
In this directory there are single files as well as folders.
Some of those folders could also have subfolders, etc.
What I am trying to do is find all of the files in this directory that start with "Incidences" and read each csv into a pandas data frame.
I am able to loop through all the files and get the names, but cannot read them into data frames.
I am getting the error that "___.csv" does not exist, as it might not be directly in the directory, but rather in a folder in another folder in that directory.
I have been trying the attached code.
inc_files2 = []
pop_files2 = []
for root, dirs, files in os.walk(directory):
for f in files:
if f.startswith('Incidence'):
inc_files2.append(f)
elif f.startswith('Population Count'):
pop_files2.append(f)
for file in inc_files2:
inc_frames2 = map(pd.read_csv, inc_files2)
for file in pop_files2:
pop_frames2 = map(pd.read_csv, pop_files2)
You are adding only file name to the lists, not their path. You can use something like this to add paths instead:
inc_files2.append(os.path.join(root, f))
You have to add the path from the root directory where you are
Append the entire pathname, not just the bare filename, to inc_files2.
You can use os.path.abspath(f) to read the full path of a file.
You can make use of this by making the following changes to your code.
for root, dirs, files in os.walk(directory):
for f in files:
f_abs = os.path.abspath(f)
if f.startswith('Incidence'):
inc_files2.append(f_abs)
elif f.startswith('Population Count'):
pop_files2.append(f_abs)

Checking and displaying files with os.walk()

The intended purpose of the program is to walk through the operating system's directories starting from path and collect every file while passing it to the check() function. This function seems to work fine in printing every file even if the check() line was replaced with a simple print(file) so where am I going wrong in executing this? Should I be storing all files in a list and then afterwards reading from that list to perform my actions?
for paths, subdirs, files in os.walk(path, topdown=True):
for file in files:
check(file)
Maybe, you need the filepath, not the filename.
for paths, subdirs, files in os.walk(path, topdown=True):
for file in files:
check(os.path.join(paths, file))

iterating through folders and from each use one specific file in a method python

What I want to do is iterate through folders in a directory and in each folder find a file 'fileX' which I want to give to a method which itself needs the file name as a parameter to open it and get a specific value from it. So 'method' will extract some value from 'fileX' (the file name is the same in every folder).
My code looks something like this but I always get told that the file I want doesn't exist which is not the case:
import os
import xy
rootdir =r'path'
for root, dirs, files in os.walk(rootdir):
for file in files:
gain = xy.method(fileX)
print gain
Also my folders I am iterating through are named like 'folderX0', 'folderX1',..., 'folderX99', meaning they all have the same name with increasing ending numbers. It would be nice if I could tell the program to ignore every other folder which might be in 'path'.
Thanks for the help!
os.walk returns file and directory names relative to the root directory that it gives. You can combine them with os.path.join:
for root, dirs, files in os.walk(rootdir):
for file in files:
gain = xy.method(os.path.join(root, file))
print gain
See the documentation for os.walk for details:
To get a full path (which begins with top) to a file or directory in dirpath, do os.path.join(dirpath, name).
To trim it to ignore any folders but those named folderX, you could do something like the following. When doing os.walk top down (the default), you can delete items from the dirs list to prevent os.walk from looking in those directories.
for root, dirs, files in os.walk(rootdir):
for dir in dirs:
if not re.match(r'folderX[0-9]+$', dir):
dirs.remove(dir)
for file in files:
gain = xy.method(os.path.join(root, file))
print gain

Categories