[Script] Global Search/Replace - Copy Search Results for Lines, Full File Content of All Results and More

Hey folks,

When I first alluded to a script like this, I had fuse.js leveraging Obsidian Query Language as my search engine for the script. I said there that I didn’t want to share the script with that plugin as overhead: more plugins need to be installed, no regex support in fuse.js, and extra layer of vault content cache all combined to keep me from sharing what I was creating.

A second thing that kept me from sharing was this: I’m not a developer. I prompt bots to get what I need. Yes, some coding savvy and some perseverance are indeed needed to tell the bots what you need and discard what you obviously don’t need, know when to take over the bot or start a new chat session, etc.
All I’m saying is that I’ve put this together for my own needs. But…

…I decided to share it after all, because…

…there is no functionality (that I know of) available at the moment to copy search results based on searches…

The script does modify file content is when we try to Copy Links or Embeds where no block ID’s were on lines (you can only do this individually anyway). The script adds a randomly generated Obsidian standard blockID and based on content adds a necessary line afterward or not. That’s the only thing it does in the way of modifying. You don’t need to use that functionality. It’s just something I’ve added along the way.

  • By the way, I didn’t allow adding blockID’s to footnotes, only main body lines. You’ll see a notice regarding this.

I’ve taken care to use only Obsidian API functionality in the script. No custom constructs are employed. We can thank 2025 bots for this as my main source of inspiration has been the forum, not Obsidian API docs.

A word to power users: copying content of thousands of results is possible, but may be slow or cause UI lag in Obsidian or your OS. So use the script reasonably, especially on mobile.

Finally, on what search method has been implemented and how it works, especially on mobile:
The script uses app.vault.cachedRead(); it leverages Obsidian’s existing, optimized cache, but as with the normal Obsidian core search, you need to search once to populate the cache. If you search with a property field filter and some search term first, that’s not going to cut it, meaning a second search after this will still take long because not all markdown content has been cached in.
So on mobile especially, make sure you search in the core modal first or if you search with this script, allow plenty of time to have the results come in. A second search will be now very fast, just as in the core modal.


:man_detective: Vault Search Extended Guide

A user-friendly search and batch copy tool for your Obsidian vault.
Find, filter, and copy results (lines or full file content) with a sleek, responsive modal.


:rocket: Prerequisites & Setup

  1. Obsidian app (of course!)
  2. CodeScript Toolkit plugin by @mnaoumov.
    • Install from Community Plugins.
    • In the plugin’s settings, specify the folder where you’ll put your .ts scripts (e.g., SYSTEM/TEMPLATE/CODE/user_scripts/codescript_toolkit_scripts/custom).
  3. Download & Unzip
    • Download Vault-Search-Extended.ts (see provided zip file).
    • Unzip and place the .ts file in your CodeScript Toolkit scripts folder.

Zip:
Removed


:gear: Configuration

  • No config changes are required for basic use!
  • If you want to exclude certain folders from search, edit the excludedFolders array at the top of the script.
  • All modal sizing and filter settings are in the CONFIG section, but defaults are sensible for most users.

To get more out of the script, what you still need to do is edit the .ts file in order to add your custom properties. You can even do this in any editor while Obsidian is open.
I’ve only added dates and a status property for you to see the syntax used, but even the date property field may not be correct, as I use snake_case, and your property for dates may not be this exact same format. You’ll need to change it and add your own props. You can add as many as you want.


:computer_mouse: How to Use

  1. Run the script from the command palette or your preferred method, be it a shortcut combination you set.
  2. Search Modal:
    • Enter your search (supports regex; more on that below).
    • Use filter tabs to narrow by frontmatter properties you specified in CONFIG (e.g., author, date).
    • Sort your results in ways you want: again, if it’s custom dates, you need to add them in CONFIG as I did (again, for you to see the structure).
    • See your recent searches for quick access (specify file name in CONFIG).
  3. Results Modal:
    • Copy mode: At the top, choose what “Copy all results” will do:
      • Matching lines only: Just the lines that matched.
      • File content no YAML: Full file content, but YAML frontmatter is stripped.
      • File content w/ YAML: Full file content, including YAML.
    • Filter results: Use the filter box to further narrow results (supports regex).
      • When you filter only the line or file content based on the filter will be copied to the clipboard.
    • Copy all results: Copies all visible results according to your selected mode.
    • To Results: Opens all matching files at the relevant line.
    • Copy/Copy Link/Copy Embed: Copy a single result (line) or its block link with or without the embed ! character.
      • Copy Link and Copy Embed function as Create+Copy Link/Embed when no blockID was found on the line.
        • There are rules for this: I have tried to go into all uses cases and determined this should suffice. If you want to make absolutely sure the blockID-packing link works, paste it embed fashion in some markdown file to see if it works.

:memo: Example Workflow

  1. Run the script.
  2. Search for cat|dog to find all lines with “cat” or “dog”.
  3. Filter by author or date or whatever you set from your property fields, if needed.
  4. In the results modal, select “File content no YAML” and click “Copy all results” to get clean markdown for workflows like RStudio, Pandoc, or any Markdown-to-LaTeX pipeline.

🔎 Regex Search Tips (click to expand!)

The script uses case insensitive searches and does not cater to word boundaries. Regex results will find results based on ‘contains’, so if you enter ‘dog,’ you’ll get results for dog, Doglas, doggie, etc.

  • OR: Use the pipe symbol | to match either term.
    cat|dog → lines containing “cat” OR “dog”

  • AND: Use .*? between terms to require both (in order).
    cat.*?dog → lines containing “cat” followed by “dog”

  • AND (any order):
    (?=.*cat)(?=.*dog) → lines containing BOTH “cat” AND “dog” (any order) – this is quite slow on large vaults and did not develop highlighting for these cases

  • Grouping:
    (cat|dog).*?jaguar → lines with “cat” OR “dog”, followed by “jaguar”

  • You can use any valid JavaScript regex!


:hammer_and_wrench: Features

  • Responsive, mobile-friendly modals
  • Batch open all results at the right line
  • Copy block links for precise referencing
  • Search history for quick repeat queries
    • Formerly used term will be brought up in recents when used again.
  • Filter by frontmatter properties you set

What it looks like

Obsidian_wG3M5di4FI


What it does

Try it. Edit the CONFIG with your props. Copy away. You can see what you get on your clipboard. I tried to make all functionality as intuitive as possible.

BTW, it is the filename above the results line you need to click to be taken to the line in the file. I tried to override Remember Cursor Position plugin positions but it may not be perfect for all cases.


:red_question_mark: Questions or Feedback?

Reply here.
If you find a bug, let me know.


Headsup

I’ve seen lately two posts where users looked for similar functionality.

One was here. There may have been at least 4-5 cases in the past where people wanted this functionality.
A moderator listed posts about the requests and currently available methods here.

The script can be useful to tackle this problem, @Sunnaq445. Try it on mobile. See in CONFIG about corrent results limits set at 500. Which means don’t search for general terms like work but work.*?New York or something like that. You can try to increase 500 to 5000 of course and see if your device can handle it.

Edits

200625: Fixed a bug when no search results were found the Search Modal stayed open and a subsequent search was not initiated. Modal now closes and you need to fire script again.
If you downloaded script before, you need to re-download again and re-add your config details again.
Also, some automatic linting made the script not work on mobile. Fixed.
Apologies.

Also, fixed escaping special characters when you have text selected and run the script.
Yes, you can have selected and run the command and have the search term added automatically. Escaping is for regex functionality so double square brackets, alias pipes, and blockID carets are escaped when copying lines with wikilinks.

250625: Edited out parts as only dual Search/Replace version available to download now.
See further down.

2 Likes

I’ve decided to fully revamp the UI and administer changes, fix couple of bugs and will be back with ver. 2. where optional full vault regex replacement will be possible.
In the meantime, I removed the download option from first post (noticed some irregularities).
Will be back with a shiny new version in the coming days.

Cheers.

Haven’t tried this yet but I’m pretty sure I made a feature request for this some time ago. Excited to try this out!

Will ship soon.

1 Like

You’re not a developer? I think not. This is an awesome effort in an area not addressed.

Looking forward to seeing how this goes. And it gives me a reason to dive into js more.

Thank You!

1 Like

No, a developer should be ‘certified’. I can handle a welder but don’t judge the seam.

So as I said, just trying to address this area that I don’t see having handled for 4-5 years. Especially 3:

  • Copy results (lines or full file content) based on searches.
  • Easy addition of property (field and value) filters based on existing values from metadatacache (no DataView need installed either). No need to write stuff into the core search modal manually or make dozens of bookmarks and edit them. Horrible, especially on mobile. I have nearly lost my eyesight completely these last few years.
  • Global search and replace. When you just want to quickly correct a stupid typo. I will add regex support but I will advise users to not use this if there are dedicated software. I will even add 2-3 layers of protective measures against mass modifying stuff vaultwide.
    • I’ll add support for users to add their own date modified dates, not just to filter by but to update the stamp by the format they use in their templates on each replacement. So the date modified type of (DV/Bases) queries check out.

Yeah, even us writing fools need to get into this because now we can build our own custom tools, down to very detailed stuff.

I like this developer’s plugin because you can easily add 50-60 pseudo-plugins to it without having to manage plugins with their own manifests. If they do simple things with config you set for yourself, I don’t see a point in developing them into a full-blown plugin.

And one of the advantages of the Codescript Toolkit plugin made scripts over Templater scripts is having native Obsidian modals in typescript env.

The latest 2025 bots are able to write these .ts files pretty consistently, if you feed them this example:

import { App, Plugin } from 'obsidian';

const reloadActivePage = async (app: App): Promise<void> => {
    app.workspace.activeLeaf?.rebuildView();
};

export class ReloadPagePlugin extends Plugin {
    async onload() {
        this.addCommand({
            id: 'reload-page',
            name: 'Reload page',
            callback: () => reloadActivePage(this.app)
        });
    }
}

export async function invoke(app: App): Promise<void> {
    return reloadActivePage(app);
}

This is the syntax they need to go by in order to have the script work on mobile as well as PC.


The script is now ready I think… Just need some more tests and a new guide.

1 Like

So here we go, ladies and gentlemen!

Do not look for Version 1.0, I said I had scrapped it. Do not look for Version 2.0; I have not published it. We are jumping to goodies territory straight away.

But I admit that it is not so straightforward so we will take it step by step.

Read the guide I’ll put together (which is almost as long as the script now but I’m sure some nice details have been left out):

Zip to download:
Global-Search-Or-Replace.zip (36.7 KB)


Note: The currently set styles for modal dimensions were set at a zoomed out Obsidian workbench, so if you use the huge-everything original 100% Obsidian window zoom, you may want to re-tweak the numbers or zoom out in Obsidian Appearance setting.


Acknowledgements

Codescript Toolkit plugin courtesy of @mnaoumov
Share Note plugin kindly shared by @AlanG


:red_question_mark: Questions or Feedback?

Reply here.
If you have a hard time setting it up or find a bug, let me know.


Edit 250625:

Added a fix for native <input type="date"> and <select> issues on older devices mostly for stylistic reasons.
Before and After come as two selectabled choices next to each other and date picker was changed.
People with newer devices will not mind this slight UI change.
But do note that the custom date picker now enforces the YYYY-MM-DD format when entering dates: this is the valid, unambiguous date setting in the UI.
Of course, this change does not affect the ability of the script to handle your notes’ date values: it continues to handle a wide variety of date formats (such as YYYY-MM-DD, YYYYMMDD, YY-MM-DD, YYMMDD, and more). So take this as a quirk of the date adding process, nothing else.
Another fix to custom date picker was also added.

260625: Another fix was added.

Please redownload .zip and re-add .ts to your vault.