πŸ•΅️πŸ“ Local File Search Tool (Part 2): Folder Search

  

If you missed the article on building a Python tool for searching local files, then I recommend you take a look here πŸ•΅️ Progressive building a File Search Tool in Python before reading this article. If you are a Techelopment gold reader 😊, you already know the tool we are talking about. 

In this article we will see how to evolve the tool to extend the search to folders too πŸ“. 

πŸ”— Do you like Techelopment? Check out the site for all the details!

Objective

The goal of this evolution of the tool is to extend the search beyond file names, to also include the folder names in the file system. This way, the user can locate not only documents, images, or other files that match the search criterion, but also directories that contain that name. The general behavior remains the same:

  • Full filesystem search (with os.walk)
  • Total search time
  • Results display
  • Ability to open found folders
  • No duplication in the folder list
  • Added πŸ“„ icon for files and πŸ“ icon for folders in search results

The extension is completely transparent to the user: just enter a name and the program searches everywhere, in files and folders.


Code

import os
import time
import subprocess
import platform

def open_folder(path):
    system = platform.system()

    if system == "Windows":
        os.startfile(path)
    elif system == "Darwin":  # macOS
        subprocess.Popen(["open", path])
    else:  # Linux
        subprocess.Popen(["xdg-open", path])


while True:
    root = input("Search in (or type 'exit' to quit'): ").strip()
    if root.lower() == "exit":
        print("Program terminated.")
        break

    if not os.path.isdir(root):
        print("Invalid path.\n")
        continue

    name = input("File or folder name (or type 'exit' to quit'): ").strip()
    if name.lower() == "exit":
        print("Program terminated.")
        break

    print("\nSearching...")
    start_time = time.time()

    found_paths = []  # now contains both files and folders

    for path, dirs, files in os.walk(root):

        # ---- search inside folder names ----
        for dirname in dirs:
            if name.lower() in dirname.lower():
                folder_path = os.path.join(path, dirname)
                found_paths.append(folder_path)
                print("πŸ“ Found folder:", folder_path)

        # ---- search inside file names ----
        for filename in files:
            if name.lower() in filename.lower():
                file_path = os.path.join(path, filename)
                found_paths.append(file_path)
                print("πŸ“„ Found file:", file_path)

    duration = time.time() - start_time
    print(f"\nSearch completed in {duration:.3f} seconds.")

    if not found_paths:
        print("No files or folders found.\n")
        continue

    # Extract unique folders from results
    unique_folders = set()

    for p in found_paths:
        if os.path.isdir(p):
            # p is a found folder
            unique_folders.add(p)
        else:
            # p is a file → use its parent directory
            unique_folders.add(os.path.dirname(p))

    unique_folders = sorted(unique_folders)

    # Ask user if they want to open a folder
    while True:
        print("\nWould you like to open one of the folders?")
        print("Enter the number to open it, or type 'no' to continue.\n")

        for i, folder in enumerate(unique_folders, 1):
            print(f"{i}) {folder}")

        choice = input("> ").strip()

        if choice.lower() == "no":
            print("")
            break

        if choice.isdigit():
            index = int(choice)
            if 1 <= index <= len(unique_folders):
                folder = unique_folders[index - 1]
                print(f"Opening: {folder}")
                open_folder(folder)
            else:
                print("Invalid number.")
        else:
            print("Invalid input.")


Example Output

Searching...
πŸ“„ Found file: C:\Users\Example\Desktop\project.txt
πŸ“„ Found file: C:\Users\Example\Desktop\project.xlsx
πŸ“ Found folder: C:\Users\Example\Desktop\Project

Search completed in 0.041 seconds.

Would you like to open one of the folders?
Enter the number to open it, or type 'no' to continue.
1) C:\Users\Example\Desktop
2) C:\Users\Example\Project
> 2
Opening: C:\Users\Example\Desktop\Project

How it works

To add the search also in the folder names, the program uses the structure already provided from os.walk().
This function returns three elements:

for path, dirs, files in os.walk(root):
  • path → current directory explored
  • dirs → list of folders contained in path
  • files → list of files contained in path

In the previous version, only files were scanned. Now, with a few added lines, the program also checks each folder name:

for dirname in dirs:
   if name.lower() in dirname.lower():
      folder_path = os.path.join(path, dirname)
      found_paths.append(folder_path)
      print("Found folder:", folder_path)

What happens in detail

  1. For each directory visited, the program scrolls through the list of folders (dirs).
  2. It compares the folder name with the search term, ignoring case.
  3. If there is a match, it constructs the full path and adds it to the results.
  4. As with files, the path is immediately displayed to the user.
  5. Finally, the program extracts the unique list of folders from the found results (files or folders).
  6. The user sees all relevant folders and can open them with a number.


Conclusion

Thanks to this change, the search engine becomes more powerful and comprehensive, while remaining simple and readable.

Happy searching πŸ”Ž!


 


Follow me #techelopment

Official site: www.techelopment.it
facebook: Techelopment
instagram: @techelopment
X: techelopment
Bluesky: @techelopment
telegram: @techelopment_channel
whatsapp: Techelopment
youtube: @techelopment