I had this same issue and wished glob.glob had an optional parameter to include dot files. I wanted to be able to include ALL dot files in ALL directories including directories that start with dot. Its just not possible to do this with glob.glob. However I found that Python has pathlib standard module which has a glob function which operates differently, it will include dot files. The function operates a little differently, in particular it does not return a list of strings, but instead path objects. However I used the following
files=[]
file_refs = pathlib.Path(".").glob(pattern)
for file in file_refs:
files.append(str(file))
The other noticeable difference I found was a glob pattern ending with **. This returned nothing in the pathlib version but would return all the files in the glob.glob one. To get the same results I added a line to check if the pattern ended with ** and if so then append /* to it.
The following code is a replacement for your example that include the files in directories starting with dot
import pathlib
for fileref in pathlib.Path('/path/').glob('**/*.ext'):
filename = str(fileref)
print(filename)
Answer from waterjuice on Stack OverflowI had this same issue and wished glob.glob had an optional parameter to include dot files. I wanted to be able to include ALL dot files in ALL directories including directories that start with dot. Its just not possible to do this with glob.glob. However I found that Python has pathlib standard module which has a glob function which operates differently, it will include dot files. The function operates a little differently, in particular it does not return a list of strings, but instead path objects. However I used the following
files=[]
file_refs = pathlib.Path(".").glob(pattern)
for file in file_refs:
files.append(str(file))
The other noticeable difference I found was a glob pattern ending with **. This returned nothing in the pathlib version but would return all the files in the glob.glob one. To get the same results I added a line to check if the pattern ended with ** and if so then append /* to it.
The following code is a replacement for your example that include the files in directories starting with dot
import pathlib
for fileref in pathlib.Path('/path/').glob('**/*.ext'):
filename = str(fileref)
print(filename)
From python 3.11 onward it is possible to do:
glob.iglob('/path/*', include_hidden=True)
Instead of:
path.rglob('*')
Try this:
path.rglob('[!.]*') if not os.path.isdir(p)
Unfortunately I can't test now, but hopefully it'll do.
How about something like:
visible = filter(
lambda path: not any((part for part in path.parts if part.startswith("."))),
Path("my_path").rglob("*")
)
You can write one yourself:
import os
def listdir_nohidden(path):
for f in os.listdir(path):
if not f.startswith('.'):
yield f
Or you can use a glob:
import glob
import os
def listdir_nohidden(path):
return glob.glob(os.path.join(path, '*'))
Either of these will ignore all filenames beginning with '.'.
This is an old question, but seems like it is missing the obvious answer of using list comprehension, so I'm adding it here for completeness:
[f for f in os.listdir(path) if not f.startswith('.')]
As a side note, the docs state listdir will return results in 'arbitrary order' but a common use case is to have them sorted alphabetically. If you want the directory contents alphabetically sorted without regards to capitalization, you can use:
sorted((f for f in os.listdir() if not f.startswith(".")), key=str.lower)
(Edited to use key=str.lower instead of a lambda)
You can use the GLOBIGNORE variable to hide the . and .. directories. This does automatically also set the dotglob option, so * now matches both hidden and non-hidden files. You can again manually unset dotglob, though, this then gives the behavior you want.
See this example:
$ ls -a
. .. a .a ..a
$ GLOBIGNORE=".:.."
$ shopt -u dotglob
$ echo * # all (only non-hidden)
a
$ echo .* # all (only hidden)
.a ..a
Note the following corner cases shown by numerous users in the comments:
.and..are always ignored as long asGLOBIGNOREhas a non-null value.GLOBIGNORE=":" ; echo .*, for instance, would work for the example above, even though it is less readable.- If you want to match hidden directories only (and not all hidden files) and therefore glob with a trailing slash,
echo .*/, you need to setGLOBIGNORE='.:..:./:../', because the glob will match./and../, which must be excluded explicitly to prevent them from showing up in the result.
The first glob below requires a leading dot and at least one additional non-dot character. These two globs together will match any possible hidden files, including files with more than one leading dot, but not . or .., which is exactly what you asked for.
ls -ld .[!.]* ..?*