Skip to content

Instantly share code, notes, and snippets.

@highfestiva
Last active August 29, 2015 14:02
Show Gist options
  • Save highfestiva/c679d69e8622a2fa6ea1 to your computer and use it in GitHub Desktop.
Save highfestiva/c679d69e8622a2fa6ea1 to your computer and use it in GitHub Desktop.
Fuzzy finding a path given a directory, say 'Deploy/31337 Application/SETTINGS.INI' would find 'deployment/application_12/settings.xml'. Now includes support for partial wildcards in a glob-like method.
#!/usr/bin/env python3
from glob import glob as doglob
import difflib
import os
def _match_ratio(s1,s2):
return difflib.SequenceMatcher(None,s1.lower(),s2.lower()).ratio()
def find(basepath, fuzzypath, thresold=0.7):
fuzzypaths = fuzzypath.replace('\\','/').split('/')
for fuzzypath in fuzzypaths:
try: paths = os.listdir(basepath)
except: return
paths = sorted(paths, key=lambda p:_match_ratio(fuzzypath,p), reverse=True)
if not paths or _match_ratio(fuzzypath,paths[0]) < thresold:
return
basepath = os.path.join(basepath, paths[0])
return basepath
def glob(path):
path = path.replace('\\','/')
if '*' in path:
path,wildcard = path.rsplit('/',1)
paths = glob(path)
if '*' in wildcard:
paths = [doglob(os.path.join(p,wildcard)) for p in paths]
paths = [item.replace('\\', '/') for sublist in paths for item in sublist] # Flatten.
else:
subpath = wildcard
paths = [find(p, subpath) for p in paths]
paths = [p for p in paths if p]
else:
try:
os.listdir(path)
paths = [path]
except:
paths = []
return paths
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment