Why does my code delete everything in the folder? - python

I wrote code to detect all the .exe files in a directory but instead it deletes everything in the folder. How can I change the code to make it delete only the .exe files?
import os
import shutil
dir_name = "/Users/plapl/Downloads/"
source = os.listdir("/Users/plapl/Downloads/")
for files in source:
if files.endswith(".exe"):
shutil.rmtree(dir_name, files)

You can only delete directories with shutil.rmtree but not files (See https://docs.python.org/3/library/shutil.html#shutil.rmtree).
You should use pathlib or os instead.
os.remove(f'{dir_name}/{files}')
pathlib.Path(f'{dir_name}/{files}').unlink()

shutil.rmtree removes the entire directory specified by its first argument. The second argument to shutil.rmtree is ignore_errors, telling the function whether to ignore errors that occur. It is not a file to remove.
shutil.rmtree is a completely inappropriate tool for the job you want to do. You need something like os.remove.

Related

Python add prefix to file names inside a directory

I need to add a prefix to file names within a directory. Whenever I try to do it though, it tries to add the prefix to the beginning of the file path. That won't work. I have a few hundred files that I need to change, and I've been stuck on this for a while. Have any ideas? Here's the closest I've come to getting it to work. I found this idea in this thread: How to add prefix to the files while unzipping in Python? If I could make this work inside my for loop to download and extract the files that would be cool, but it's okay if this happens outside of that loop.
import os
import glob
import pathlib
for file in pathlib.Path(r'C:\Users\UserName\Desktop\Wells').glob("*WaterWells.*"):
dst = f"County_{file}"
os.rename(file, os.path.join(file, dst))
That produces this error:
OSError: [WinError 123] The filename, directory name, or volume label syntax is incorrect: 'C:\\Users\\UserName\\Desktop\\Wells\\Alcona_WaterWells.cpg' -> 'C:\\Users\\UserName\\Desktop\\Wells\\Alcona_WaterWells.cpg\\County_C:\\Users\\UserName\\Desktop\\Wells\\Alcona_WaterWells.cpg'
I'd like to add "County_" to each file. The targeted files use this syntax: CountyName_WaterWells.ext
os.path.basename gets the file name, os.path.dirname gets directory names. Note that these may break if your slashes are in a weird direction. Putting them in your code, it would work like this
import os
import glob
import pathlib
for file in pathlib.Path(r'C:\Users\UserName\Desktop\Wells').glob("*WaterWells.*"):
dst = f"County_{os.path.basename(file)}"
os.rename(file, os.path.join(os.path.dirname(file), dst))
The problem is your renaming variable, dst, adds 'County_' before the entire path, which is given by the file variable.
If you take file and break it up with something like file.split("/") (where you should replace the slash with whatever appears between directories when you print file to terminal) then you should be able to get file broken up as a list, where the final element will be the current filename. Modify just this in the loop, put the whole thing pack together using "".join(_path + modified_dst) and then pass this to os.rename.

what does the "shutil.rmtree" do?

I saw the following codes on website:
import tempfile
import shutil
dirpath = tempfile.mkdtemp()
# ... do stuff with dirpath
shutil.rmtree(dirpath)
I know that "shutil.rmtree" is delete an entire directory tree. But why delete the directory just after it was built?
I fond one answer said:"If you use this in a test be sure to remove (shutil.rmtree) the directory because it's not automatically deleted after use." But after I tried, even without "shutil.rmtree", the directory I just built will be deleted after restart computer.
So what does the "shutil.rmtree" do?
The directory is created in a temporary location that your system may choose to delete at some point in the future.
If you know you're done with the temporary directory created, you can remove it yourself using shutil.rmtree immediately.

Iterating over .wav files in subdirectories of parent directory

Cheers everybody,
I need help with something in python 3.6 exactly. So i have structure of data like this:
|main directory
| |subdirectory's(plural)
| | |.wav files
I'm currently working from a directory where main directory is placed so I don't need to specify paths before that. So firstly I wanna iterate over my main directory and find all subdirectorys. Then in each of them I wanna find the .wav files, and when done with processing them I wanna go to next subdirectory and so on until all of them are opened, and all .wav files are processed. Exactly what I wanna do with those .wav files is input them in my program, process them so i can convert them to numpy arrays, and then I convert that numpy array into some other object (working with tensorflow to be exact, and wanna convert to TF object). I wrote about the whole process if anybody has any fast advices on doing that too so why not.
I tried doing it with for loops like:
for subdirectorys in open(data_path, "r"):
for files in subdirectorys:
#doing some processing stuff with the file
The problem is that it always raises error 13, Permission denied showing on that data_path I gave him but when I go to properties there it seems okay and all permissions are fine.
I tried some other ways like with os.open or i replaced for loop with:
with open(data_path, "r") as data:
and it always raises permission denied error.
os.walk works in some way but it's not what I need, and when i tried to modify it id didn't give errors but it also didnt do anything.
Just to say I'm not any pro programmer in python so I may be missing an obvious thing but ehh, I'm here to ask and learn. I also saw a lot of similiar questions but they mainly focus on .txt files and not specificaly in my case so I need to ask it here.
Anyway thanks for help in advance.
Edit: If you want an example for glob (more sane), here it is:
from pathlib import Path
# The pattern "**" means all subdirectories recursively,
# with "*.wav" meaning all files with any name ending in ".wav".
for file in Path(data_path).glob("**/*.wav"):
if not file.is_file(): # Skip directories
continue
with open(file, "w") as f:
# do stuff
For more info see Path.glob() on the documentation. Glob patterns are a useful thing to know.
Previous answer:
Try using either glob or os.walk(). Here is an example for os.walk().
from os import walk, path
# Recursively walk the directory data_path
for root, _, files in walk(data_path):
# files is a list of files in the current root, so iterate them
for file in files:
# Skip the file if it is not *.wav
if not file.endswith(".wav"):
continue
# os.path.join() will create the path for the file
file = path.join(root, files)
# Do what you need with the file
# You can also use block context to open the files like this
with open(file, "w") as f: # "w" means permission to write. If reading, use "r"
# Do stuff
Note that you may be confused about what open() does. It opens a file for reading, writing, and appending. Directories are not files, and therefore cannot be opened.
I suggest that you Google for documentation and do more reading about the functions used. The documentation will help more than I can.
Another good answer explaining in more detail can be seen here.
import glob
import os
main = '/main_wavs'
wavs = [w for w in glob.glob(os.path.join(main, '*/*.wav')) if os.path.isfile(w)]
In terms of permissions on a path A/B/C... A, B and C must all be accessible. For files that means read permission. For directories, it means read and execute permissions (listing contents).

Errno13, Permission denied when trying to read file

I have created a small python script. With that I am trying to read a txt file but my access is denied resolving to an no.13 error, here is my code:
import time
import os
destPath = 'C:\Users\PC\Desktop\New folder(13)'
for root, dirs, files in os.walk(destPath):
f=open(destPath, 'r')
.....
Based on the name, I'm guessing that destPath is a directory, not a file. You can do a os.walk or a os.listdir on the directory, but you can't open it for reading. You can only call open on a file.
Maybe you meant to call open on one or more of the items from files
1:
I take it you are trying to access a file to get what's inside but don't want to use a direct path and instead want a variable to denote the path. This is why you did the destPath I'm assuming.
From what I've experienced the issue is that you are skipping a simple step. What you have to do is INPUT the location then use os.CHDIR to go to that location. and finally you can use your 'open()'.
From there you can either use open('[direct path]','r') or destPath2 = 'something' then open(destPath2, 'r').
To summarize: You want to get the path then NAVIGATE to the path, then get the 'filename' (can be done sooner or not at all if using a direct path for this), then open the file.
2: You can also try adding an "r" in front of your path. r'[path]' for the raw line in case python is using the "\" for something else.
3: Try deleting the "c:/" and switching the / to \ or vice versa.
That's all I got, hope one of them helps! :-)
I got this issue when trying to create a file in the path -C:/Users/anshu/Documents/Python_files/Test_files . I discovered python couldn't really access the directory that was under the user's name.
So, I tried creating the file under the directory - C:/Users/anshu/Desktop .
I was able to create files in this directory through python without any issue.

Running bash scripts within newly created folders based on file names

I'm not sure even where to start.
I have a list of output files from a program, lets call them foo. They are numbered outputs like foo_1.out
I'd like to make a directory for each file, move the file to its directory, run a bash script within that directory, take the output from each script, copy it to the root directory as a concatenated single file.
I understand that this is not a forum for "hey, do my work for me", I'm honestly trying to learn. Any suggestions on where to look are sincerely appreciated!
Thanks!
You should probably look up the documentation for the python modules os - specifically os.path and a couple of others - and subprocess which can be found here and here respectively.
Without wanting to do it all for you as you stated - you'll be wanting to do something like:
for f in filelist:
[pth, ext] = os.path.splitext(f)
os.mkdir(pth)
out = subprocess.Popen(SCRIPTNAME, stdout=...)
# and so on...
To get a list of all files in a directory or make folders, check out the os module. Specifically, try os.listdir and os.mkdir
To copy files, you could either manually open each file, copy the contents to a string, and rewrite it to a different file. Alternatively, look at the shutil module
To run bash scripts, use the subprocess library.
All three of those should be a part of python's standard library.

Categories