0

For example in the my_dir structure folder there are 4 files:

  1. README.md
  2. readme.md
  3. my_ReadMe.md
  4. what.md

I want my function to return only files that look like fname, so the README.md, readme.md and my_ReadMe.md

from glob import glob as gl

fname = 'readme.md'
my_dir = '/my_dir'

files = gl(f'{my_dir}/**/{fname}', recursive=True)
if files:
    # do stuff
anas
  • 9
  • 4
  • 3
    When you say "look like", it needs to be more specific. My guess would be you want it to match if the filename includes a non case-sensitive copy of fname? – dwb Jul 24 '20 at 11:06
  • They all have the same file ending ... need to keep that in mind – Paul Erlenmeyer Jul 24 '20 at 11:09
  • yes @dantechguy sorry for my superficiality, and i want it to match if filename include the keyword 'readme.md' so ok if the file is called for example 'thereadmefile.md', the important thing is that the keyword is present. – anas Jul 24 '20 at 11:12

3 Answers3

2

Get a list of all file names source

from os import listdir
from os.path import isfile, join
files = [f for f in listdir(mypath) if isfile(join(mypath, f))]

Loop through each file name, and check if the lowercase version includes fname

for name in files:
    if fname in name.lower():
        print(name)

If you want to find all files, then looking at the link i provided earlier you can find the following code to find all files:

from os import walk
files = []
for (dirpath, dirnames, filenames) in walk(mypath):
    files.extend(filenames)
dwb
  • 2,136
  • 13
  • 27
  • very useful, but if the file it's somewhere in a complex folder structure? for example mypath/folder1/folder2/readme.md, can't find it – anas Jul 24 '20 at 11:30
0

Loop through the list of files in your directory and compare with re.search:

import re
files=['README.md','readme.md','my_readme.md','what.md']
query='readme.md'
print([file for file in files if re.search(query , file, re.IGNORECASE)])
Alex S
  • 231
  • 1
  • 10
  • I get the feeling regex might be *slight* overkill haha – dwb Jul 24 '20 at 11:15
  • Yup, my mind just went streight to case insensitive comparison, and it was the first one i though of. The calling lower to allow direct comparsion is probably the easier implementation – Alex S Jul 24 '20 at 11:18
0

Assuming that you are looking to match all .md files that "look like" - defined here as containing the sub-string readme (case insensitive) - from within the directory specified by my_dir and all sub-directories contained within, the following should work for you.

import glob
import os

my_dir = 'my_dir' # IMPORTANT Please note that the leading '/' has been removed, this is to allow for desired behaviour in os.path.join() below

files = [ i for i in glob.glob(os.path.join(my_dir, '**', '*.md'), recursive=True) if 'readme' in os.path.basename(i.lower()) ]
if files:
    # do stuff

It makes use of the builtin os module to construct the path passed to glob.glob that will search the top-level directory passed as the my_dir variable recursively and return all paths ending with a .md file.

The list of .md file paths returned by the invocation of glob.glob is filtered (by way of a list comprehension) to only include paths ending in .md files containing the sub-string readme (case insensitive).

The result is a list of all paths from within the my_dir tree that end in an .md file containing the case insensitive sub-string readme within the filename portion of the path - or an empty list if none are found.

JPI93
  • 1,507
  • 5
  • 10
  • how sensual is your solution? – anas Jul 24 '20 at 14:41
  • @anas "sensual"? :') Assuming that's an autocorrect mistake and you mean "sensible", quite. It meets the criteria of returning a list of all `.md` files containing the substring `readme` (case insensitive) recursively from a given directory as outlined in your original question reliably. If no such files are present in the target tree it will return an empty list that will not execute the code contained in the `if files:` block as per your original post. – JPI93 Jul 24 '20 at 14:49
  • 2
    actually i really meant 'sensual', in one line of code you have enclosed the resolution of a rather complex problem, moreover to the third argument of the join I could also add a list of extensions for example "`*.{md, txt, ...}`" – anas Jul 24 '20 at 15:00