I have a script that will pull files from two directories back, so the script resides at:
/folder2/folder1/folder0/script.py
and the files that will be processed will be in folder2.
I can get back one level with "..//" (I'm making a Windows executable with cx_free) but I'm thinking this isn't the best way to do this.
I am setting an input directory and an output directory. I want to keep the paths relative to the location of the script so that "folder2" can be moved without screwing up the functionality of the script or force rewriting of it.
thanks
First you get the directory where your script is located, like so:
current_dir = os.path.dirname(os.path.realpath(__file__))
And then, if you know you will always use the directory two levels above, just use:
target_dir = os.path.join(current_dir, '..', '..')
From there you can manipulate files from the target_dir as you please.
Edit
From adsmith, instead of joining two ".." paths together, you can instead define target_dir as:
target_dir = os.path.sep.join(current_dir.split(os.path.sep)[:-2])
Which will simply cut off the last two directories in your path, instead of them ending in a few uglier ".."s. So, the first method would look something like:
/path/to/folder2/folder1/directory/../..
Whereas the second implementation would be:
/path/to/folder2/
I would use your suggested method of os.chdir(r'..\..') to make sure your current working directory is in folder2. I'm not really sure what you're asking though, so maybe clarify why you think this ISN'T the right solution?
Related
I am facing simple problem, but can't get my head around it.
I have millions of millions files, in millions of directories I need to delete.
Windows can't handle it as it's crushing before it even starts deleting. Tries Linux script but that didn't really work.
I decided to write my own program to do that. Idea is simple:
Check if there is a folder in the root path, if there is, go in it, check for folder if it's there go in and that until there is no folders, then delete all the files in that folder then delete that folder, and start again until root directory is empty.
I started trying to use OS library.
So far I got:
import os
rootdir = 'D:/TEST/'
global current_dir
current_dir = rootdir
global dir_counter
dir_counter=0
while (os.listdir(rootdir)[1]):
print(current_dir)
if(os.listdir(current_dir)[1]):
if (os.path.isdir(os.path.join(current_dir,os.listdir(current_dir)[dir_counter+1]))):
current_dir = os.path.join(current_dir,os.listdir(current_dir)[dir_counter+1])
dir_counter = dir_counter+1
I was trying just to test if it's going in directories to the end, but unfortunately it goes only one level and stays there.
My folder structure
TEST1->FOLDER->FOLDER2->FOLDER3
TEST2
TEST3
Since your need isn't really tied to python, you might consider trying some of the techniques described here:
https://superuser.com/questions/741945/delete-all-files-from-a-folder-and-its-sub-folders?answertab=votes#tab-top
I need to make a script that will iterate through all the directories inside a directory. It should go into each directory, get its name and save it to a variable and comes back out, and then loops.
for dir in os.walk(exDir):
path = dir
os.chdir(path)
source = #dir trimmed to anything after the last /
os.chdir("..")
loops
It needs to go into the directory to do other things not mentioned above. I've only just started Python and have been stuck on this problem for the last day or so.
For each iteration of your for loop, dir is a tuple of format (filepath, subdirectories, files). As such dir[0] will give you the filepath.
It sounds like you just want to os.chdir for each folder recursively in exDir in which case the following will work:
for dir in os.walk(exDir):
os.chdir(dir[0])
...
I'm using Glob.Glob to search a folder, and the sub-folders there in for all the invoices I have. To simplify that I'm going to add the program to the context menu, and have it take the path as the first part of,
import glob
for filename in glob.glob(path + "/**/*.pdf", recursive=True):
print(filename)
I'll have it keep the list and send those files to a Printer, in a later version, but for now just writing the name is a good enough test.
So my question is twofold:
Is there anything fundamentally wrong with the way I'm writing this?
Can anyone point me in the direction of how to actually capture folder path and provide it as path-variable?
You should have a look at this question: Python script on selected file. It shows how to set up a "Sent To" command in the context menu. This command calls a python script an provides the file name sent via sys.argv[1]. I assume that also works for a directory.
I do not have Python3.5 so that I can set the flag recursive=True, so I prefer to provide you a solution which you can run on any Python version (known up to day).
The solution consists in using calling os.walk() to run explore the directories and the set build-in type.
it is better to use set instead of list as with this later one you'll need more code to check if the directory you want to add is not listed already.
So basically you can keep two sets: one for the names of files you want to print and the other one for the directories and their sub folders.
So you can adapat this solution to your class/method:
import os
path = '.' # Any path you want
exten = '.pdf'
directories_list = set()
files_list = set()
# Loop over direcotries
for dirpath, dirnames, files in os.walk(path):
for name in files:
# Check if extension matches
if name.lower().endswith(exten):
files_list.add(name)
directories_list.add(dirpath)
You can then loop over directories_list and files_list to print them out.
I am using os.walk to run through a tree of directories check for some input files and then run a program if the proper inputs are there. I notice I am having a problem because of the away that os.walk is evaluating the root variable in the loop:
for root, dirs, files in os.walk('.'):# I use '.' because I want the walk to
# start where I run the script. And it
# will/can change
if "input.file" in files:
infile = os.path.join(root,"input.file")
subprocess.check_output("myprog input.file", Shell=True)
# if an input file is found, store the path to it
# and run the program
This is giving me an issue because the infile string looks like this
./path/to/input.file
When it needs to look like this for the program to be able to find it
/home/start/of/walk/path/to/input.file
I want to know if there is a better method/ a different way to use os.walk such that I can leave the starting directory arbitrary, but still be able to use the full path to any files that it finds for me. Thanks
The program I am using is written by me in c++ and I suppose I could modify it as well. But I am not asking about how to do that in this question just to clarify this question is about python's os.walk and related topics that is why there is no examples of my c++ code here.
Instead of using ., convert it to the absolute path by using os.path.abspath("."). That will convert your current path to an absolute path before you begin.
I would like to change the cwd to a specific folder.
The folder name is known; however, the path to it will vary.
I am attempting the following but cannot seem to get what I am looking for:
absolute_path = os.path.abspath(folder_name)
directory_path = os.path.dirname(absolute_path)
os.chdir(directory_path)
This does not do what I'm looking for because it is keeping the original cwd to where the .py file is run from. I've tried adding os.chdir(os.path.expanduser("~")) prior to the first code block; however, it just creates the absolute_path to /home/user/folder_name.
Of course if there is a simple import that I could use, I'll be open to anything.
What would be the correct way to get the paths of all folders with with a specific name?
def find_folders(start_path,needle):
for cwd, folders, files,in os.walk(start_path):
if needle in folders:
yield os.path.join(cwd,needle)
for path in find_folders("/","a_folder_named_x"):
print path
all this is doing is walking down your directory structure from a given start path and finding all occurances of a folder named needle
in the example it is starting at the root folder of the system and looking for a folder named "a_folder_named_x" ... be forwarned this could take a while to run if you need to search the whole system ...
You need to understand that abspath accepts a relative pathname (which might just be a filename), and gives you the equivalent absolute (full) pathname. A relative pathname is one that begins in your current directory; no searching is involved, and so it always points to one place (which may or may not exist).
What you actually need is to search down a directory tree, starting at ~ or whatever directory makes sense in your case, until you find a folder with the requested name. That's what #Joran's code does.