I try to put a listing of subdirectories of a directory into a list.
I use that code :
import os
for dirname, dirnames, filenames in os.walk("W:/test"):
# print path to all subdirectories first.
for subdirname in dirnames:
a= os.path.join(dirname, subdirname)
liste = []
liste.append(a)
print liste
The problem is that I have not all my subdirectories into my list "liste"
Would you have any solutions ?
Thanks
You need to call liste.append inside the loop.
import os
liste = []
for root, dirs, files in os.walk(path):
for subdir in dirs:
liste.append(os.path.join(root, subdir))
print(liste)
Related
I have a folder structure:
I am using os.walk(path) to get all the files from the "test" folder. I would like to all files except the folder "B" and the files inside it.
test (root-folder)
t1.txt
t2.txt
A
f.txt
B
f1.txt
C
f4.txt
list1 = ['A', 'C']
result = [os.path.join(dp, f) for dp, dn, filenames in os.walk(path) for f in filenames if os.path.splitext(f)[1] == '.txt']
for items in result:
for fname in list1:
if fname in items.lower():
result.remove(items)
print(result)
I tried it, but it takes only the A and C. Not the files in main folder? Can you help? Where am i wrong?
Thank you
Possible solution is to use glob library:
import glob
dir_to_exclude = ['B', 'C']
files = glob.glob('**/*.txt', recursive=True)
files_paths = [_ for _ in files if _.split("\\")[0] not in dir_to_exclude]
files_names = [_.split("\\")[-1] for _ in files if _.split("\\")[0] not in dir_to_exclude]
print(f'List of file names with path: {files_paths}')
print(f'List of file names: {files_names}')
I think this should work
file_paths = []
forbidden_path = GetForbiddenPath()
for root, dirs, files in os.walk(path):
for name in files:
file_path = os.path.join(root, name)
if forbidden_path in file_path:
if os.path.splitext(file_path)[1] == '.txt':
file_paths += [file_path]
Lets say the directories hierarchy looks like this:
A(root)
|
B---------C--------D
| | |
fileB.h fileC.png fileD.py
fileC1.jpg
E
|
fileE.py
How can I access all the doc? Or just get the path. Is there a way to iterlate all?
What I do:
path = sys.path[0]
for filename_dir in os.listdir(path):
filename, ext = os.path.splitext(filename_dir)
if ext == '.h':
#do something
elif ext == '.png'
#do something
.....
But as I know listdir can only access the directory where my program's py file located.
This gives only the dirs and files under a directory, but not recursively:
import os
for filename in os.listdir(path):
print filename
If you want to list absolute paths:
import os
def listdir_fullpath(d):
return [os.path.join(d, f) for f in os.listdir(d)]
If you want resursive search, this gives you an iterator that returns 3-tuples including the parent directory, list of directories, and list of files at each iteration:
for i,j,k in os.walk('.'):
print i, j, k
For example:
import os
path = sys.path[0]
for dirname, dirnames, filenames in os.walk(path):
for subdirname in dirnames:
print "FOUND DIRECTORY: ", os.path.join(dirname, subdirname)
for filename in filenames:
print "FOUND FILE: ", os.path.join(dirname, filename)
I want to return the path of a file, If it is found by the program, but I want it to continue to loop(or recursively repeat) the program until all files are checked.
def findAll(fname, path):
for item in os.listdir(path):
n = os.path.join(path, item)
try:
findAll(n, fname)
except:
if item == fname:
print(os.idontknow(item))
So I'm having trouble with calling the path, right now I have
os.idontknow(item)
as a place holder
Input is :
findAll('fileA.txt', 'testpath')
The output is:
['testpat\\fileA.txt', 'testpath\\folder1\\folder11\\fileA.txt','testpath\\folder2\\fileA.txt']
Per my comment above, here is an example that will start at the current directory and search through all sub-directories, looking for files matching fname:
import os
# path is your starting point - everything under it will be searched
path = os.getcwd()
fname = 'file1.txt'
my_files = []
# Start iterating, and anytime we see a file that matches fname,
# add to our list
for root, dirs, files in os.walk(path):
for name in files:
if name == fname:
# root here is the path to the file
my_files.append(os.path.join(root, name))
print my_files
Or as a function (more appropriate for your case :) ):
import os
def findAll(fname, start_dir=os.getcwd()):
my_files = []
for root, dirs, files in os.walk(start_dir):
for name in files:
if name == fname:
my_files.append(os.path.join(root, name))
return my_files
print findAll('file1.txt')
print findAll('file1.txt', '/some/other/starting/directory')
Something like this, maybe?
import os
path = "path/to/your/dir"
for (path, dirs, files) in os.walk(path):
print files
This is the original block of code and its result:
Code:
if os.path.isdir(top):
for root, dirs, files in os.walk(top, topdown = True):
for dirname in dirs:
print 'Dirname = ', os.path.join(root, dirname)
Results:
Dirname = ../output/.svn
Dirname = ../output/a random folder
Dirname = ../output/a random folder - copy
Dirname = ../output/.svn\pristine
Dirname = ../output/.svn\temp
Dirname = ../output/.svn\pristine\04
Dirname = ../output/.svn\pristine\59
Dirname = ../output/a random folder\another one inside
Dirname = ../output/a random folder\another one inside - Copy
Dirname = ../output/a random folder\another one inside - Copy (2)
Now I want to ignore all hidden folders and subfolders. This is the modified code and its result:
Code:
if os.path.isdir(top):
for root, dirs, files in os.walk(top, topdown = True):
for dirname in dirs:
print 'Dirname = ', os.path.join(root, dirname)
if dirname.startswith('.'):
dirs.remove(dirname)
Result:
Dirname = ../output/.svn
Dirname = ../output/a random folder - copy
Dirname = ../output/a random folder\another one inside
Dirname = ../output/a random folder\another one inside - Copy
Dirname = ../output/a random folder\another one inside - Copy (2)
What I don't understand is: why is ../output/a random folder not listed anymore??
You should not modify an iterable while you're iterating over it. In this case, you're modifying dirs inside of a for loop that iterates over dirs.
Try this instead:
if os.path.isdir(top):
for root, dirs, files in os.walk(top, topdown = True):
dirs_to_ignore = []
for dirname in dirs:
print 'Dirname = ', os.path.join(root, dirname)
if dirname.startswith('.'):
dirs_to_ignore.append(dirname)
for dirname in dirs_to_ignore:
dirs.remove(dirname)
See also: Modifying list while iterating
I want a dictionary of files:
files = [files for (subdir, dirs, files) in os.walk(rootdir)]
But I get,
files = [['filename1', 'filename2']]
when I want
files = ['filename1', 'filename2']
How do I prevent looping through that tuple? Thanks!
Both of these work:
[f for (subdir, dirs, files) in os.walk(rootdir) for f in files]
sum([files for (subdir, dirs, files) in os.walk(rootdir)], [])
Sample output:
$ find /tmp/test
/tmp/test
/tmp/test/subdir1
/tmp/test/subdir1/file1
/tmp/test/subdir2
/tmp/test/subdir2/file2
$ python
>>> import os
>>> rootdir = "/tmp/test"
>>> [f for (subdir, dirs, files) in os.walk(rootdir) for f in files]
['file1', 'file2']
>>> sum([files for (subdir, dirs, files) in os.walk(rootdir)], [])
['file1', 'file2']
for (subdir, dirs, f) in os.walk(rootdir): files.extend(f)
files = [filename for (subdir, dirs, files) in os.walk(rootdir) for filename in files]
import os, glob
files = [file for file in glob.glob('*') if os.path.isfile(file)]
if your files have extensions, then even simpler:
import glob
files = glob.glob('*.*')