Limit replace to bookmarked lines? Or something else...



  • I need to replace or delete a string on lines matching or containing another string. Working with cisco configs, need to remove log from all lines containing permit. I guess I need to limit replace to bookmarked lines? Help!



  • @J-T

    There is no way to scope a search to previously bookmarked lines, although wouldn’t that be nice?

    If you care to share some data with some good before and after examples, perhaps something could be crafted to do the job all in one operation…



  • @Alan-Kilborn said:

    There is no way to scope a search to previously bookmarked lines

    Well…no way to do it without scripting. Scripting can do almost anything. :)



  • @J-T , welcome to the Notepad++ Community forum.

    @Alan-Kilborn said:

    Well…no way to do it without scripting.

    Though scripting is great, you can also do two-step or three-step regex, like@Terry-R suggested in the recent 32-character question, which can overcome some of those limitations

    For example, assuming @J-T 's data looks something like this

    This line has log but not the other keyword
    This line has log in a line continaing permit
    This line has permit and wants to remove log from it
    This line has permit but not the word to remove
    

    The first regex should look for (?-s)^(?=.*permit) and replace with EDITTHISLINE:
    The second regex could be something like (?-s)(^EDITTHISLINE:)(.*)(log)(.*)$ with the replace of \2\4 to delete the EDITTHISLINE: and the log from the line, but keep the other text from before and after log. If there are still lines with EDITTHISLINE: prefix, the prefix can be removed with a third regex, (?-s)^EDITTHISLINE: replace with blank/empty. (with some experimenting, I could probably get it down to be able to delete the EDITTHISLINE in the second regex, even if there is no log… but sometimes, if it’s simpler to understand, doing a third regex is worth it.)

    When I run those three regex, I get

    This line has log but not the other keyword
    This line has  in a line continaing permit
    This line has permit and wants to remove  from it
    This line has permit but not the word to remove
    

    @J-T : This is a rough approximation based on your vague specs. You may want to include whitespace before and/or after your match of log, to make spacing come out right, or something similar.

    -----
    FYI: I often add this to my response in regex threads, unless I am sure the original poster has seen it before. Here is some helpful information for finding out more about regular expressions, and for formatting posts in this forum (especially quoting data) so that we can fully understand what you’re trying to ask:

    This forum is formatted using Markdown, with a help link buried on the little grey ? in the COMPOSE window/pane when writing your post. For more about how to use Markdown in this forum, please see @Scott-Sumner’s post in the “how to markdown code on this forum” topic, and my updates near the end. It is very important that you use these formatting tips – using single backtick marks around small snippets, and using code-quoting for pasting multiple lines from your example data files – because otherwise, the forum will change normal quotes ("") to curly “smart” quotes (“”), will change hyphens to dashes, will sometimes hide asterisks (or if your text is c:\folder\*.txt, it will show up as c:\folder*.txt, missing the backslash). If you want to clearly communicate your text data to us, you need to properly format it.

    If you have further search-and-replace (“matching”, “marking”, “bookmarking”, regular expression, “regex”) needs, study this FAQ and the documentation it points to. Before asking a new regex question, understand that for future requests, many of us will expect you to show what data you have (exactly), what data you want (exactly), what regex you already tried (to show that you’re showing effort), why you thought that regex would work (to prove it wasn’t just something randomly typed), and what data you’re getting with an explanation of why that result is wrong. When you show that effort, you’ll see us bend over backward to get things working for you. If you need help formatting, see the paragraph above.

    Please note that for all regex and related queries, it is best if you are explicit about what needs to match, and what shouldn’t match, and have multiple examples of both in your example dataset. Often, what shouldn’t match helps define the regular expression as much or more than what should match.



  • Ha. Well, I’ll qualify my earlier statement this way “no way to do it…in a very reasonable action”. :)

    Most people that aren’t already fairly familiar with regex aren’t going to be able to follow some “complex” multi-step procedure.

    It still seems that some sample data from the OP could take this down to a really simple (for regex) single-step replacement. Could be wrong, of course.



  • So in the spirit of my earlier reply, here’s a Pythonscript that fulfills the title of this thread; it is a bit simple-minded, but could easily be extended to handle regular expressions.

    bookmark_mask = 1 << 24
    
    if editor.markerNext(0, bookmark_mask) == -1:
    
        notepad.messageBox('To use this, need to have at least one bookmarked line; you have zero', '')
    
    else:
    
        find_what = notepad.prompt('Enter text to find:', '', '')
    
        if find_what != None and len(find_what) > 0:
    
            replace_with = notepad.prompt('Enter replacement text:', '', '')
    
            if replace_with != None:
    
                editor.beginUndoAction()
    
                line_nbr = editor.markerNext(0, bookmark_mask)
                while line_nbr != -1:
                    start_pos = editor.positionFromLine(line_nbr)
                    end_pos = start_pos + len(editor.getLine(line_nbr)) - 1
                    editor.rereplace(find_what, replace_with, 0, start_pos, end_pos)
                    line_nbr = editor.markerNext(line_nbr + 1, bookmark_mask)
    
                editor.endUndoAction()


  • @Alan-Kilborn said:

    here’s a Pythonscript that fulfills the title of this thread;

    Nice.

    I’m not sure that “run a regex to bookmark, then run a PythonScript to edit” is any less confusing to the typical user than “run these 2-3 regex in sequence”… but that’s still a good alternative.

    Really, with one more prompt at the beginning of your script ("Enter the keyword, such as ‘permit’: "), and using PythonScript to set the bookmarks rather than making the user manually bookmark, PythonScript could be made to handle it. (Or, skipping bookmarks, just wrap the editor.rereplace inside of the while loop with pseudocode if line contains KEYWORD then editor.rereplace.)

    I made my mods, and was just about to post, when I re-read the title of the message, and it indicated “bookmarked lines”, so my avoiding of bookmarking my be going too far, in the OP’s opinion. But since I’d already made the script changes, I might as well include it.

    ----
    As you said, this won’t handle regex in the search/replace… but it does handle the simple case described in the original post, and goes a step further by not requiring marking the matching lines first.

    # encoding=utf-8
    """in response to https://notepad-plus-plus.org/community/topic/17550"""
    from Npp import *
    
    keyword = notepad.prompt('Enter keyword to search for:', '', 'permit')
    find_what = notepad.prompt('Enter text to find:', '', 'log')
    
    if find_what != None and len(find_what) > 0 and keyword != None and len(keyword)>0:
        replace_with = notepad.prompt('Enter replacement text:', '', '')
    
        if replace_with != None:
    
            editor.beginUndoAction()
            nLines = editor.getLineCount()
    
            for line_nbr in range(0, nLines):
                start_pos = editor.positionFromLine(line_nbr)
                str = editor.getLine(line_nbr)
                end_pos = start_pos + len(str) - 1
                if keyword in str:
                    editor.rereplace(find_what, replace_with, 0, start_pos, end_pos)
    
            editor.endUndoAction()
    


  • @PeterJones said:

    I’m not sure that “run a regex to bookmark, then run a PythonScript to edit” is any less confusing to the typical user than “run these 2-3 regex in sequence”

    A difference of philosophy. The OP already had his lines bookmarked, the script is decanted down to picking a menu item: e.g. “ReplaceAllOnBookmarkedLinesOnly”. So really it satisfies what was originally asked for, without a lot of mumbo-jumbo and smoke and mirrors with an obscure multistep regex (although those tools are good to have in one’s knowledge toolbox). :)

    Of course, there is the whole install-PS-if-you-don’t-have-it-already hurdle… ;)


Log in to reply