Introduction
If you write a lot of Python scripts or Jupyter notebooks on your Mac, you may eventually face a very frustrating problem: you remember a variable name, a function name, or a small piece of code, but you cannot remember which file contains it.
Table of contents
- Introduction
- Search inside Jupyter notebooks using grep
- Explanation of the command
- Search for a variable name
- Search inside all Jupyter notebooks in your home folder
- Search for several keywords in the same notebook
- Search inside Python scripts
- Search inside many code file types
- Display the matching lines
- A better tool: ripgrep
- Search for several terms with ripgrep
- Recommended workflow
- Search inside an external hard drive
- Create a small reusable search function
- Create a faster version using ripgrep
- Conclusion
- References
For example, I recently needed to find a notebook containing code like:
1 | idx_start, idx_end, delta_start_sec, fraction_start = compute_subset_indices_from_start(...) |
I knew the code was somewhere on my Mac, probably inside a .ipynb file, but I could not remember the exact notebook name or folder. Using the normal macOS Finder search was not very useful. Finder is fine when searching for file names, documents, or common metadata, but it is not always the best tool when you need to search inside code files, especially Jupyter notebooks.
A Jupyter notebook is not a simple .py file. It is actually a structured JSON file that contains code cells, markdown cells, outputs, and metadata. This means that searching inside notebooks is possible, but using Terminal tools is often much more reliable than using Finder.
In this tutorial, we will see how to search inside .ipynb, .py, and other code files on a Mac using Terminal.
Search inside Jupyter notebooks using grep
The simplest solution is to use grep, a command-line tool that searches for text patterns inside files.
Open the Terminal app and run:
1 | grep -RIl --include="*.ipynb" "compute_subset_indices_from_start" ~/Documents ~/Desktop ~/Downloads 2>/dev/null |
This command searches recursively inside your Documents, Desktop, and Downloads folders for Jupyter notebooks containing the text:
1 | compute_subset_indices_from_start
|
If a match is found, the command prints the path of the notebook.
Example output:
/Users/yourname/Documents/projects/fire_analysis/matching_viirs_gitco.ipynb
You can then open the notebook with:
1 | open "/Users/yourname/Documents/projects/fire_analysis/matching_viirs_gitco.ipynb" |
Explanation of the command
1 | grep -RIl --include="*.ipynb" "compute_subset_indices_from_start" ~/Documents ~/Desktop ~/Downloads 2>/dev/null |
Here is what each part means:
1 | grep
|
Searches for text inside files.
1 | -R |
Searches recursively inside folders and subfolders.
1 | -I |
Ignores binary files.
1 | -l |
Only prints the file names that contain the matching text.
1 | --include="*.ipynb" |
Only searches files ending with .ipynb.
1 | "compute_subset_indices_from_start"
|
The text you want to find.
1 | ~/Documents ~/Desktop ~/Downloads |
The folders where the search will be performed.
1 | 2>/dev/null |
Hides permission errors and other warning messages.
Search for a variable name
If you remember a variable name, you can search for it directly.
For example:
1 | grep -RIl --include="*.ipynb" "idx_start" ~/Documents ~/Desktop ~/Downloads 2>/dev/null |
Or:
1 | grep -RIl --include="*.ipynb" "delta_start_sec" ~/Documents ~/Desktop ~/Downloads 2>/dev/null |
This is useful when you do not remember the full function name but remember one variable used in the code.
Search inside all Jupyter notebooks in your home folder
If you are not sure where the notebook is located, you can search your entire home directory:
1 | grep -RIl --include="*.ipynb" "compute_subset_indices_from_start" ~ 2>/dev/null |
This is more complete, but it can take longer if you have many files.
Search for several keywords in the same notebook
Sometimes one keyword is not enough. For example, you may want to find notebooks that contain all of these terms:
1 2 3 4 5 | idx_start idx_end delta_start_sec fraction_start compute_subset_indices_from_start |
You can use:
1 2 3 4 5 6 7 | grep -RIl --include="*.ipynb" "compute_subset_indices_from_start" ~/Documents ~/Desktop ~/Downloads 2>/dev/null | while read f; do grep -q "idx_start" "$f" && grep -q "idx_end" "$f" && grep -q "delta_start_sec" "$f" && grep -q "fraction_start" "$f" && echo "$f" done |
This command first finds notebooks containing:
1 | compute_subset_indices_from_start
|
Then it checks whether the same notebook also contains:
1 2 3 4 | idx_start idx_end delta_start_sec fraction_start |
Only notebooks containing all these terms are printed.
Search inside Python scripts
If you want to search inside .py files instead of notebooks, use:
1 | grep -RIl --include="*.py" "compute_subset_indices_from_start" ~/Documents ~/Desktop ~/Downloads 2>/dev/null |
To search both Python scripts and Jupyter notebooks, you can run:
1 | grep -RIl --include="*.py" --include="*.ipynb" "compute_subset_indices_from_start" ~/Documents ~/Desktop ~/Downloads 2>/dev/null |
Search inside many code file types
If your code may be inside Python files, notebooks, shell scripts, markdown notes, or text files, you can use:
1 2 3 4 5 6 7 8 | grep -RIl \ --include="*.py" \ --include="*.ipynb" \ --include="*.sh" \ --include="*.md" \ --include="*.txt" \ "compute_subset_indices_from_start" \ ~/Documents ~/Desktop ~/Downloads 2>/dev/null |
This is useful if you sometimes copy code snippets into notes or documentation files.
Display the matching lines
The previous commands only show the file names. If you want to see the matching lines too, remove the -l option and add -n:
1 | grep -RIn --include="*.ipynb" "compute_subset_indices_from_start" ~/Documents ~/Desktop ~/Downloads 2>/dev/null |
The -n option prints the line number where the match was found.
However, because .ipynb files are JSON files, the output can sometimes be difficult to read. It is still useful to identify the notebook, but for detailed reading it is usually better to open the notebook itself.
A better tool: ripgrep
Another excellent tool is ripgrep, often called with the command rg.
It is usually faster than grep, especially when searching large folders with many files.
You can install it using Homebrew:
1 | brew install ripgrep |
Then search inside notebooks with:
1 | rg -l --glob "*.ipynb" "compute_subset_indices_from_start" ~/Documents ~/Desktop ~/Downloads |
To search your entire home folder:
1 | rg -l --glob "*.ipynb" "compute_subset_indices_from_start" ~ |
To search inside both .py and .ipynb files:
1 | rg -l --glob "*.py" --glob "*.ipynb" "compute_subset_indices_from_start" ~ |
Search for several terms with ripgrep
You can search for several possible keywords using a regular expression:
1 | rg -n --glob "*.ipynb" "idx_start|idx_end|delta_start_sec|fraction_start|compute_subset_indices_from_start" ~ |
This command finds notebooks containing any of these terms:
1 2 3 4 5 | idx_start idx_end delta_start_sec fraction_start compute_subset_indices_from_start |
This is very useful when you only remember part of the code.
Recommended workflow
A good workflow is:
1) Start with the most specific function name
1 | grep -RIl --include="*.ipynb" "compute_subset_indices_from_start" ~/Documents ~/Desktop ~/Downloads 2>/dev/null |
2) If nothing is found, search for a variable name
1 | grep -RIl --include="*.ipynb" "delta_start_sec" ~ 2>/dev/null |
3) If you have ripgrep, use
1 | rg -n --glob "*.ipynb" "idx_start|idx_end|delta_start_sec|fraction_start|compute_subset_indices_from_start" ~ |
4) Once you find the notebook, open it
1 | open "/path/to/notebook.ipynb" |
Search inside an external hard drive
If your code is stored on an external drive, for example:
1 | /Volumes/HD15TB/Datasets/ |
you can search it with:
1 | grep -RIl --include="*.ipynb" "compute_subset_indices_from_start" /Volumes/HD15TB/Datasets/ 2>/dev/null |
Or with ripgrep:
1 | rg -l --glob "*.ipynb" "compute_subset_indices_from_start" /Volumes/HD15TB/Datasets/ |
This is very useful when you have many old projects stored on an external disk.
Create a small reusable search function
If you often search for code on your Mac, you can create a small shell function.
Open your shell configuration file:
1 | nano ~/.zshrc |
Add this function:
1 2 3 4 5 6 7 8 9 | findcode() { grep -RIl \ --include="*.py" \ --include="*.ipynb" \ --include="*.sh" \ --include="*.md" \ "$1" \ ~/Documents ~/Desktop ~/Downloads 2>/dev/null } |
Save the file, then reload your shell:
1 | source ~/.zshrc |
Now you can search your code like this:
1 | findcode "compute_subset_indices_from_start" |
or:
1 | findcode "delta_start_sec" |
Create a faster version using ripgrep
If you have installed ripgrep, you can add this to your ~/.zshrc file:
1 2 3 4 5 6 7 8 9 | findcode_rg() { rg -l \ --glob "*.py" \ --glob "*.ipynb" \ --glob "*.sh" \ --glob "*.md" \ "$1" \ ~/Documents ~/Desktop ~/Downloads } |
Then reload:
1 | source ~/.zshrc |
Use it with:
1 | findcode_rg "compute_subset_indices_from_start" |
Conclusion
When you need to retrieve an old script or Jupyter notebook on your Mac, searching with Finder may not be enough. Finder is not always the best tool for searching inside code files, especially when the file is a Jupyter notebook.
Using Terminal commands such as grep or ripgrep gives you a much more reliable way to search for function names, variables, keywords, or small code snippets.
For example, if you remember a function like:
1 | compute_subset_indices_from_start
|
or variables like:
1 2 3 4 | idx_start idx_end delta_start_sec fraction_start |
you can quickly find the notebook or script where they were used.
For developers, data scientists, and researchers who often work with many notebooks and scripts, learning how to search inside files from the command line can save a lot of time.
References
| Links | Site |
|---|---|
| Terminal User Guide for Mac | Apple Support |
| Get started with Terminal on Mac | Apple Support |
| grep manual | Linux man-pages |
| ripgrep GitHub repository | GitHub |
| Jupyter Notebook file format | Jupyter nbformat documentation |
| Project Jupyter | Project Jupyter |
