How to search within notebooks on Windows 10?
Here is a potential workaround.
Windows 10 has a feature called the Windows Subsystem for Linux. You should be able to activate from the start menu and typing "Windows Features" and selecting the first hit. Then, turn it on as shown in the image.
Linux has a command called grep that provides many options to search text files. After installing, you can type bash
into the start window and use the bash command shell to search files using grep. For example, the command grep -RH NotebookDirectory --include="*.nb" *
will perform a recursive directory search for the term NotebookDirectory
for all files matching the pattern *.nb
.
Updated More Robust Answer
I have a Windows 7 and 10 system that both have the Linux emulator Cygwin installed. Since the Windows 10 machine has both Cygwin
and the Subsystem for Linux
, it can be confusing about which Linux system was called. It turns out that grep
is stored in /bin/grep
and /usr/bin/grep
for the Subsystem for Linux
and Cygwin
, respectively.
I used the linux command which grep
and RunProcess
to confirm that my initial answer was picking up the Cygwin
grep.
RunProcess[{"which", "grep"}, "StandardOutput"]
(* "/usr/bin/grep" *)
To access the Subsystem for Linux
require that we prepend bash -c
to the command or
RunProcess[{"bash", "-c", "which grep"}, "StandardOutput"]
(* "/bin/grep" *)
A more robust code that can handle either Cygwin
or the Subsystem for Linux
follows
SetDirectory[NotebookDirectory[]];
grepRecurse[searchterm_, filepattern_] := {"bash", "-c",
StringTemplate["grep -RH \"`1`\" --include=\"`2`\" *"][searchterm,
filepattern]}
cmd = grepRecurse["NotebookDirectory", "Int*.nb"];
s = RunProcess[cmd, "StandardOutput"];
Column@StringSplit[StringSplit[s, RegularExpression["\r?\n"]], ":"][[
All, 1]]
Original Answer That Might Only Work with Cygwin in Path
Alternatively, you can issue the command from Mathematica directly using RunProcess
workflow as shown below.
SetDirectory[NotebookDirectory[]];
grepRecurse[searchterm_, filepattern_] := {"grep", "-RH",
StringTemplate["\"`1`\""][searchterm],
StringTemplate["--include=\"`1`\""][filepattern], "*"};
cmd = grepRecurse["NotebookDirectory", "Int*.nb"];
s = RunProcess[cmd, "StandardOutput"];
Column@StringSplit[StringSplit[s, RegularExpression["\r?\n"]],
":"][[All, 1]]
Some time ago I've written a search routine which allows searching inside of Notebooks using string patterns:
- Searching a phrase in all *.nb files
Other solutions from that thread can also be of interest for you.
Alternatively you can program your own search routine on the base of one of the following functions:
Import[nbFilePath, "Plaintext"]
NotebookImport[nb, _ ->"InputText"]
First[FrontEndExecute[FrontEnd`ExportPacket[nb, "PlainText"]]]
You can find additional information on their usage in the following threads:
Programmatically convert notebook input cells to text file
How to convert arbitrary raw boxes directly into String?
Note however that Import[nbFilePath, "Plaintext"]
is based on "NBImport.exe" which has long-standing bug in importing files with non-ASCII filepaths.