import os
import argparse
def is_allowed_char(char, allowed_chars):
"""Check if a character is allowed (either ASCII or in the allowed_chars list)."""
if char.isascii() or char in allowed_chars:
return True
return False
def contains_disallowed_chars(filename, allowed_chars):
"""Check if a filename contains any disallowed characters."""
for char in filename:
if not is_allowed_char(char, allowed_chars):
return True
return False
def find_files_and_dirs_with_disallowed_chars(root_dir, allowed_chars, maxdepth):
"""Recursively find files and directories with disallowed characters in their names up to a specified depth."""
disallowed_paths = []
for root, dirs, files in os.walk(root_dir):
depth = root[len(root_dir):].count(os.sep)
if maxdepth is not None and depth >= maxdepth:
# Modify the dirs in-place to prune the search.
dirs[:] = []
continue
for name in dirs + files:
if contains_disallowed_chars(name, allowed_chars):
disallowed_paths.append(os.path.join(root, name))
return disallowed_paths
def main():
parser = argparse.ArgumentParser(description='Find files and directories with disallowed characters.')
parser.add_argument('root_dir', type=str, help='The root directory to search.')
parser.add_argument('-a', '--allowed', type=str, default="", help='The allowed characters in addition to all ASCII characters.')
parser.add_argument('--maxdepth', type=int, default=None, help='The maximum depth to search (default is no limit).')
args = parser.parse_args()
if not os.path.isdir(args.root_dir):
print("The provided path is not a directory.")
return
allowed_chars = set(args.allowed)
disallowed_paths = find_files_and_dirs_with_disallowed_chars(args.root_dir, allowed_chars, args.maxdepth)
if disallowed_paths:
print("Files and directories with disallowed characters:")
for path in disallowed_paths:
print(path)
else:
print("No files or directories with disallowed characters found.")
if __name__ == "__main__":
main()