Maybe there is a better way, but how about:
import glob
types = ('*.pdf', '*.cpp') # the tuple of file types
files_grabbed = []
for files in types:
files_grabbed.extend(glob.glob(files))
# files_grabbed is the list of pdf and cpp files
Perhaps there is another way, so wait in case someone else comes up with a better answer.
Answer from user225312 on Stack OverflowMaybe there is a better way, but how about:
import glob
types = ('*.pdf', '*.cpp') # the tuple of file types
files_grabbed = []
for files in types:
files_grabbed.extend(glob.glob(files))
# files_grabbed is the list of pdf and cpp files
Perhaps there is another way, so wait in case someone else comes up with a better answer.
glob returns a list: why not just run it multiple times and concatenate the results?
from glob import glob
project_files = glob('*.txt') + glob('*.mdown') + glob('*.markdown')
I can grab all files in a folder with some extension using
/*.txt
Can i specify in one line that i want to grab files with different extension, like txt AND png
/*.txt + png (for example or something like that)
or do i have to make several code blocks for it?
What is the best way to glob multiple file types in Python?
Are there libraries to help with globbing in Python?
What is the difference between glob and pathlib?
What you need to do is glob for each extension. glob.glob() returns you a list, which you can then append to the rest.
So for example you could do this:
extensions = ("*.png","*.jpg","*.jpeg",)
list = []
for extension in extensions:
list.extend(glob.glob(subject_path+"/"+extension)
or more concise using a list comprehension:
list = sum([ glob.glob(subject_path+"/"+x) for x in ("*.png","*.jpg","*.jpeg") ], [])
So glob.glob() returns a list of all files that were globbed with that extension. With list.extend() you can append one list to another, so you just add all these glob results together into one list.
Glob uses the fnmatch module at the back end, maybe you can just use that directly yourself? Here's an approach with the checking out in a function to keep the body of your code cleaner:
eg.
import sys
import fnmatch
import os
def filter_files(file_list, ext_list):
for file in file_list:
for ext in ext_list:
if fnmatch.fnmatch(file, ext):
yield file
break
BASE_PATH=sys.argv[1]
EXTENSIONS= "*.jpg", "*.png", "*.gif"
for dirname, dirnames, filenames in os.walk(BASE_PATH):
matches = list(filter_files(filenames, EXTENSIONS))
I'm searching for multiple file types recursively in a directory. In this case I'm searching for multiple excel related file types. How can I search for multiple file types recursively without walking through the directories only one time? Right now, I'm searching the entire tree every time for each file type. Link to code.
A bit late to the party with a couple of single-line suggestions that don't require writing a custom function nor the use of a loop and work on Linux:
pathlib.Path.glob() takes interleaved symbols in brackets. For the case of ".txt" and ".xls" suffixes, one could write
files = pathlib.Path('temp_dir').glob('*.[tx][xl][ts]')
If you need to search for ".xlsx" as well, just append the wildcard "*" after the last closing bracket.
files = pathlib.Path('temp_dir').glob('*.[tx][xl][ts]*')
A thing to keep in mind is that the wildcard at the end will be catching not only the "x", but any trailing characters after the last "t" or "s".
Prepending the search pattern with "**/" will do the recursive search as discussed in previous answers.
If you need to use pathlib.Path.glob()
from pathlib import Path
def get_files(extensions):
all_files = []
for ext in extensions:
all_files.extend(Path('.').glob(ext))
return all_files
files = get_files(('*.txt', '*.py', '*.cfg'))
In the operator's filter_glob property, (which you've already defined), you can define multiple extensions using the ; separator, eg:
filter_glob = StringProperty(
default="*.png;*.jpg;*.jpeg;*.bmp;*.exr",
options={'HIDDEN'},
)
If you want to make a list of all extensions Blender supports you can use. bpy.path.extensions_image eg:
"*" + ";*".join(bpy.path.extensions_image)
Here is an example from http://web.purplefrog.com/~thoth/blender/python-cookbook/image-to-material-node.html :
def image_for(fname):
candidates = [ img for img in bpy.data.images if img.filepath == fname]
if len(candidates)<1:
return bpy.data.images.load(fname)
else:
return candidates[0]
def node_of_type(nodes, type):
for node in nodes:
if node.type == type:
return node
def mission1(fname):
mat = bpy.data.materials.get("material")
if mat is None:
mat = bpy.data.materials.new("material")
mat.use_nodes = True
nodes = mat.node_tree.nodes
n1 = node_of_type(nodes, "TEX_IMAGE")
if n1 is None:
n1 = nodes.new("ShaderNodeTexImage")
n1.location = (-200,0)
n1.image = image_for(fname)
bsdf = node_of_type(nodes, 'BSDF_DIFFUSE')
mat.node_tree.links.new(bsdf.inputs[0], n1.outputs[0])
coord = node_of_type(nodes, 'TEX_COORD')
if coord is None:
coord = nodes.new('ShaderNodeTexCoord')
coord.location = (-400,0)
mat.node_tree.links.new(n1.inputs['Vector'], coord.outputs['UV'])
return mat
mat = mission1("/home/thoth/art/dancing-bear/bear384.png")
bpy.context.active_object.data.materials[0] = mat
you could try:
def get_files_with_extension(my_str, exts):
for f in glob.iglob("**/*{}*.*".format(my_str), recursive = True):
if any(f.endswith(ext) for ext in exts):
yield f
You could create a list and loop over it
exten_to_find = ['.pro','bd3','.mysql']
you could format like this for iteration
files = glob.glob("**/*{x}*.{y}".format(x = myStr, y = extension_toFind), recursive = True)
from pathlib import Path
exts = [".jl", ".jsonlines"]
mainpath = "/path/to/dir"
# Same directory
files = [p for p in Path(mainpath).iterdir() if p.suffix in exts]
# Recursive
files = [p for p in Path(mainpath).rglob('*') if p.suffix in exts]
# 'files' will be a generator of Path objects, to unpack into strings:
list(files)
This worked for me:
for f in path.glob("*.[jpeg jpg png]*"):
...
As a reference fnmatch:
[seq] matches any character in seq
And in Path.glob:
Patterns are the same as for fnmatch, with the addition of “**” which means “this directory and all subdirectories, recursively”.
Edit:
Better way would be something like:
*.[jpJP][npNP][egEG]*
I didn't know the proper POSIX-compliant way of doing it. The previous way will match files like ".py" because the brackets match any letter in whatever order.
This way should match "jpeg", "JPEG", "jpg", "JPG", "png" and "PNG". It also matches formats like "jpegxyz" because of the "*" at the end but having the sequence of brackets makes it harder to pick up other file extensions.