Tag Mass Action: Add, Rename, and Delete a tag in multiple files (Tag Wrangler)

Hi @pjeby. Loving tag wrangler, particularly for renaming. Thank you

Can you add capability to search the actual tag list please? I have hundreds of tags and would like to simplify and consolidate the list. If I ‘right click’ with tag wrangler, I can get a list of notes that contain a tag I search on.

However, I want to search for the tag itself. eg: do I have a tag called ‘story’ or is it ‘storytelling’. At the moment I have to scroll through all the tags to visually inspect. A search bar at the top of the tag list would be fabulous. eg entering ‘story’ in the tag search bar, would reveal three tags #mystory #story #storytelling.

This should be a core function for Obsidian.

Hope this is something you are able to do


Thank you so much for your plugin!
I was always finding method to deal with the problem, and this just worked PERFECTLY!

It’s really helpful. :blush:

Have you considered just typing a tag in your current note to use the autosuggest?

Yes, that is what I do as a workaround.
However, there would be great value in being able to search in the tag list itself.
For example, if I wish to rename #trend to #change I need to scroll through a long list to get down to the #trend tag. Fuzzy search would bring it up immediately.
As others have observed, importing Evernote files can overwhelm the tag list, and it would be good to be able to quickly search and easily edit.

1 Like

+1 for this feature

It would really help to do this globally for the tags within the application. If I rename one tag, I’d like the option to apply this change everywhere else that the tag appears.

1 Like

I feel the need for this too, and have posted about it here.


I want it

1 Like

+1 want this feature very much.
I’m using tags as grouping instrument. It’s pain to rename tag in every related note.


very essential feature for revamping legacy naming schemes… going thru one by one is so… painful.

1 Like

This feature would be wonderful to have, please add it!

1 Like

or you could use the tag wrangler plug-in today :slight_smile:


If you want a more advanced solution. I wrote a little python script which opens a window where you can drag and drop files and the script will add tags to each file. (It will be a blank window so just drag and drop the files you want in it)

Save the script below to dragger.py. Open it and replace the “tag=” with whatever you want. (Space separated for multiple of them). Then just run the script using python batch_add_tags.py and it should do the trick.
I would firmly suggest a backup. If you mess something up, don’t blame me.
That aside, it worked pretty well for me.
I only tested this on a Linux based system with GTK and python installed. (Eg: ubuntu)

import gi
gi.require_version('Gtk', '3.0')
from gi.repository import Gtk, Gdk
import sys

tag = "uncertainty"

class GUI:
    def __init__(self):
        self.file_paths = []
        window = Gtk.Window()
        window.connect('destroy', Gtk.main_quit)

        textview = Gtk.TextView()
        #                      (drag behaviour, targets (leave empty), action)
        textview.drag_dest_set(Gtk.DestDefaults.DROP, [], Gdk.DragAction.COPY)
        # add the ability to receive URIs (e.g. file paths)
        textview.connect("drag-data-received", self.on_drag_data_received)


    def on_drag_data_received(self, widget, drag_context, x,y, data,info, time):
        #              (context, success, delete_from_source, time)
        Gtk.drag_finish(drag_context, True, False, time)

        # always call Gtk.drag_finish to receive as suggested by documentation

def format_file_paths(file_paths):
    return [i[7::].replace("%20", " ") for i in file_paths] #because gtk returns file:///

def add_tag(files, tag):
    for fname in files:
        temp = []
        with open(fname, "r") as originalfile:
            temp = [x.strip() for x in originalfile.readlines()] #remove line breaks
            if "tags" not in temp[2]:
                temp.insert(2,f"tags: {tag}") #if tag: is not present, add it
            if tag not in str(temp[2]):
                temp[2] = temp[2] + f" {tag}" #add the required tag, if not present already
        with open(fname, "w") as newfile:
            newfile.write("\n".join(temp)) #write the file

def main():
    filenames = GUI()
    filenames = format_file_paths(filenames.file_paths)
    print(f"Running on {len(filenames)} files")
    add_tag(filenames, tag)

if __name__ == "__main__":

Though scripting to modify the .md files directly might not be so difficult, I think an “official” way to do this directly from the app would be nice.


:laughing: :sweat_smile: :rofl: Hi all. I realize this is an old thread, but I am a newbie, just getting around to seriously looking the best use of tags. Afer enabling the Tag pane, I discovered that I have a bzillion tags representing phone numbers, FedEx numbers and others where I have used the hashtag symbol (#) to preface a number raher than using “No.” or some other symbol or device. As all of these tags are unique, it doesn’t seem there is way to rename them to “#null” or “#delete.” Oh, well!

Tag Wrangler does not work on mobile. Anyone with a mobile-first note taking workflow (me for one) cannot use Tag Wrangler for this feature.

1 Like

+1 for being able to easily Rename, Delete Tags more easily (and also maybe, if possible, move nested tags just through a “drag-and-drop”). Thanks!!

1 Like

+1. I’m surprised that this isn’t yet supported, tags appear to be first-class citizens in some ways because they have their own side bar panel, but not in others, unable to rename them. When you have hundreds of notes with a tag you want to rename, the only practical way to get around this is to write a script.


the only practical way to get around this is to write a script

That works. Or just install the tag wrangler plugin.

1 Like

Also sending my thanks for this plugin :pray:

I really should have read the whole thread first to see the better solutions that had already been posted. But I wrote this bash script for my own use, and I might as well dump it here:

set -e

# Search for all .md or .MD files in the current working directory.
# For each, do the indicated replacement.
find . -type f -name "*.md" -o -name "*.MD" | while read file; do
    # If the file does not contain the FROM string, skip it.
    grep -q "$FROM" "$file" || continue
    echo "Processing $file"
    sed -i "s/$FROM/$TO/g" "$file"

(I should say, really, “Github Copilot and I wrote”. My bash/find/sed ability is weak enough that it would have taken me a good half an hour to look up the right usages on my own. AI, man.)

1 Like