Reputation: 989
I've searched everywhere for this answer but can't find it.
I'm trying to come up with a script that will search for a particular subfolder then check if it contains any files and, if so, write out the path of the folder. I've gotten the subfolder search part figured out, but the checking for files is stumping me.
I have found multiple suggestions for how to check if a folder is empty, and I've tried to modify the scripts to check if the folder is not empty, but I'm not getting the right results.
Here is the script that has come the closest:
for dirpath, dirnames, files in os.walk('.'):
if os.listdir(dirpath)==[]:
print(dirpath)
This will list all subfolders that are empty, but if I try to change it to:
if os.listdir(dirpath)!=[]:
print(dirpath)
it will list everything--not just those subfolders containing files.
I would really appreciate it if someone could point me in the right direction.
This is for Python 3.4, if that matters.
Thanks for any help you can give me.
Upvotes: 58
Views: 73089
Reputation: 15568
Adding to @Jon Clements’ pathlib answer, I wanted to check if the folder is empty with pathlib but without creating a set:
from pathlib import Path
# shorter version from @vogdb
is_empty = not any(Path('some/path/here').iterdir())
# similar but unnecessary complex
is_empty = not bool({_ for _ in Path('some/path/here').rglob('*')})
vogdb method attempts to iterate over all files in the given directory. If there is no files, any() will be False. We negate it with not
so that is_empty is True
if no files and False
if files.
sorted(Path(path_here).rglob('*')) return a list of sorted PosixPah items. If there is no items, it returns an empty list, which is False. So is_empty will be True if the path is empty and false if the path have something
Similar idea results {} and [] gives the same:
Upvotes: 57
Reputation: 47978
This can now be done more efficiently in Python3.5+, since there is no need to build a list of the directory contents just to see if its empty:
import os
def is_dir_empty(path):
with os.scandir(path) as scan:
return next(scan, None) is None
Note: as of Python 3.10, pathlib.Path.iterdir
is using os.listdir
internally, so it won't perform so well on large directories compared to os.scandir
.
Upvotes: 4
Reputation: 3221
With pathlib
this can be done as follows:
import pathlib
# helper function
def is_empty(_dir: pathlib.Path) -> bool:
# return not bool([_ for _ in _dir.iterdir()])
return not any(_dir.iterdir())
# create empty dir
_dir = pathlib.Path("abc")
# check if dir empty
is_empty(_dir) # will return True
# add files to folder and call it again
Upvotes: 2
Reputation: 77337
'files' already tells you whats in the directory. Just check it:
for dirpath, dirnames, files in os.walk('.'):
if files:
print(dirpath, 'has files')
if not files:
print(dirpath, 'does not have files')
Upvotes: 38
Reputation: 4633
Check if the folder contains files:
import os
import shutil
if len(os.listdir(folder_path)) == 0: # Check is empty..
shutil.rmtree(folder_path) # Delete..
Upvotes: 4
Reputation: 3390
I have follews Bash checking if folder has contents answer.
os.walk('.')
returns the complete files under a directory and if there thousands it may be inefficient. Instead following command find "$target" -mindepth 1 -print -quit
returns first found file and quits. If it returns an empty string, which means folder is empty.
You can check if a directory is empty using
find
, and processing its output
def is_dir_empty(absolute_path):
cmd = ["find", absolute_path, "-mindepth", "1", "-print", "-quit"]
output = subprocess.check_output(cmd).decode("utf-8").strip()
return not output
print is_dir_empty("some/path/here")
Upvotes: 0
Reputation: 9418
If you can delete the directory, you can use this:
my_path = os.path.abspath("something")
try:
os.rmdir(my_path)
is_empty = True
# Do you need to keep the directory? Recreate it!
# os.makedirs(my_path, exist_ok=True)
except OSError:
is_empty = False
if is_empty:
pass
The os.rmdir only removes a directory if it is empty, otherwise it throws the OSError exception.
You can find a discussion about this on:
For example, deleting an empty directory is fine when you are planing to do a git clone, but not if you are checking beforehand whether the directory is empty, so your program does not throw an empty directory error.
Upvotes: 8
Reputation: 2774
You can directly use the generator instead of converting to a set or (ordered) list first:
from pathlib import Path
p = Path('abc')
def check_dir(p):
if not p.exists():
print('This directory is non-existent')
return
try:
next(p.rglob('*'))
except StopIteration:
print('This directory is empty')
return
print('OK')
Upvotes: 1
Reputation: 4372
You can use this simple code:
dir_contents = [x for x in os.listdir('.') if not x.startswith('.')]
if len(dir_contents) > 0:
print("Directory contains files")
It checks for files and directories in the current working directory (.
). You can change .
in os.listdir()
to check any other directory.
Upvotes: 2
Reputation: 142126
You can make use of the new pathlib
library introduced in Python 3.4 to extract all non-empty subdirectories recursively, eg:
import pathlib
root = pathlib.Path('some/path/here')
non_empty_dirs = {str(p.parent) for p in root.rglob('*') if p.is_file()}
Since you have to walk the tree anyway, we build a set of the parent directories where a file is present which results in a set of directories that contain files - then do as you wish with the result.
Upvotes: 19
Reputation: 3532
entities = os.listdir(dirpath)
for entity in entities:
if os.path.isfile(entity):
print(dirpath)
break
Upvotes: 4