Copying grep match to clipboard

418 views
Skip to first unread message

e2o

unread,
Aug 14, 2021, 4:27:06 PM8/14/21
to BBEdit Talk
Howdy! Is there an easy way to copy a chunk of text matched with a regular expression to the clipboard only? No search/replace.

I have an expression that selects everything at the beginning of a document up to but not including the first blank line. I need to copy this text and copy it to the bottom of the document. I can't use Process Lines Including because it uses \A to match beginning of document, which doesn't fly there.

So my expression is:

\A.*\r(^\S.*\r)+

How do I just copy the matched text to clipboard? This needs to be scriptable with Keyboard Maestro - so standard menu items and keyboard shortcuts would be nice, but I might be able to muddle through AppleScript or similar.

Thanks!

- eric

Patrick Woolsey

unread,
Aug 14, 2021, 4:48:42 PM8/14/21
to bbe...@googlegroups.com
The Find command is normally the easiest way to locate any text which matches a particular Grep pattern, and you can then just copy the matched (& selected) text. (Please bear in mind that you are never _obligated_ to perform a replace after a search.)

In case the above isn't what you're trying to accomplish, then it would be helpful if you could provide an actual example, e.g. a pair of "before" and "after" documents


Regards,

Patrick Woolsey
==
Bare Bones Software, Inc. <https://www.barebones.com/>

Chris

unread,
Aug 14, 2021, 6:07:30 PM8/14/21
to bbe...@googlegroups.com

Yeah, ⌘ ⌥ ⌃ G will search and select all. 
Then copy and paste. 

Also you can ⌘ ⌥ F to bring up quick search which is a little less cumbersome than the full text view. 

I’d like to recommend this post, it’s good stuff. 



--Chris

On Aug 14, 2021, at 1:48 PM, Patrick Woolsey <pwoo...@barebones.com> wrote:

The Find command is normally the easiest way to locate any text which matches a particular  Grep pattern, and you can then just copy the matched (& selected) text. (Please bear in mind that you are never _obligated_ to perform a replace after a search.)
--
This is the BBEdit Talk public discussion group. If you have a feature request or need technical support, please email "sup...@barebones.com" rather than posting here. Follow @bbedit on Twitter: <https://twitter.com/bbedit>
---
You received this message because you are subscribed to the Google Groups "BBEdit Talk" group.
To unsubscribe from this group and stop receiving emails from it, send an email to bbedit+un...@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/bbedit/E633B534-D1B9-4649-80BD-CB02804D6E16%40barebones.com.

Chris

unread,
Aug 14, 2021, 6:10:09 PM8/14/21
to bbe...@googlegroups.com
My apologies. Full text View should be full search window. 

--Chris

On Aug 14, 2021, at 3:07 PM, Chris <ch...@rustydogink.com> wrote:



e2o

unread,
Aug 14, 2021, 9:49:04 PM8/14/21
to BBEdit Talk
Oh, excellent stuff - thank  you both. Now as I try to figure out how I'll script this, my initial ideas are fairly cumbersome. Yeah, I could bring up the Find dialog, paste in the search criteria and  [ ⌘ ⌥ ⌃ G ], but is there a repeatable way using a named saved search or something? I was hoping a Text Factory would have something as simple as a Find and Copy command, but it seems to insist on a Replace. I guess I could find (myInitialLines)(thenEverythingToTheEnd) and replace with \1\2\1 - which would result in copying my initial non-blank lines to the end of the document - but that seems kinda kludgy. Maybe I have to create something in applescript along the lines of Tell application BBEdit to find blahblah and copy to clipboard...

Thanks again... - eric


jj

unread,
Aug 15, 2021, 4:33:48 AM8/15/21
to BBEdit Talk
Hi Eric,

This snippet of AppleScript might help you.

try
tell application "BBEdit"
set vText to ""
tell first document of first window
set vRegex to "(?s)\\A(.*?)\n\\s*\n" -- Captures everything at the beginning of a document up to but not including the first blank line.
set vMatch to find vRegex searching in its text options {search mode:grep, wrap around:true, backwards:false}
if vMatch's found then
set vText to grep substitution of "\\1"
if vText ≠ "" then
tell application "BBEdit" to set current clipboard to vText -- Copy captured text to clipboard.
if its last character is not in [linefeed, return] then
set vText to linefeed & vText
end if
set insertion point after its last character to linefeed & vText -- Insert captured text at EOF.
end if
end if
end tell
end tell
on error aMessage
display alert aMessage as critical
end try

HTH

Jean Jourdain

Patrick Woolsey

unread,
Aug 15, 2021, 9:37:00 AM8/15/21
to bbe...@googlegroups.com
On Aug 14, 2021, at 20:17, e2o <eeo...@gmail.com> wrote:
>
> Oh, excellent stuff - thank you both. Now as I try to figure out how I'll script this, my initial ideas are fairly cumbersome. Yeah, I could bring up the Find dialog, paste in the search criteria and [ ⌘ ⌥ ⌃ G ], but is there a repeatable way using a named saved search or something?

I'm probably missing something here :-) but why is it important that you be able to script this action: do you just want to be able to perform this operation on demand whenever you open a suitable document, or do you want to integrate it into a larger external workflow?

Again, a concrete example with steps would be extremely helpful. :-)

If however a search & replace of the form you describe below:

> find (myInitialLines)(thenEverythingToTheEnd) and replace with \1\2\1


*would* do the job then you need only create a text factory which contains a Replace All action with the specified Find and Replace patterns, then save that factory as a _text filter_ and you can assign it a key shortcut to invoke against the current document at any time.


> I was hoping a Text Factory would have something as simple as a Find and Copy command, but it seems to insist on a Replace.

For reference, text factories are designed to _transform_ whatever text you apply them to: whether the contents of the current document when run as a _text filter_, or a batch of files when run globally as a _script_, and the advantage of using a text factory is that you can easily define and apply any desired set of actions (i.e. text transformations) with no need for scripting.



> I guess I could find (myInitialLines)(thenEverythingToTheEnd) and replace with \1\2\1 - which would result in copying my initial non-blank lines to the end of the document - but that seems kinda kludgy.

If that is what you wish to accomplish then I don't see anything at all kludgy about the solution; it's an entirely valid transform.

Christopher Stone

unread,
Aug 15, 2021, 10:30:43 AM8/15/21
to BBEdit-Talk
On Aug 13, 2021, at 21:30, e2o <eeo...@gmail.com> wrote:

Howdy! Is there an easy way to copy a chunk of text matched with a regular expression to the clipboard only? No search/replace.

I have an expression that selects everything at the beginning of a document up to but not including the first blank line. I need to copy this text and copy it to the bottom of the document. I can't use Process Lines Including because it uses \A to match beginning of document, which doesn't fly there.

So my expression is:

\A.*\r(^\S.*\r)+



Hey Eric,

Your pattern does not fully match your verbal description.  Whenever asking for text processing help please always include at least one good real-world before and after example.

Doing so will always save yourself and anyone who helps you both time and aggravation.

From what I understand your task is really just a simple find/replace.

AppleScriptified:

-------------------------------------------------------------------------------------------
# Auth: Christopher Stone
# dCre: 2021/08/15 09:01
# dMod: 2021/08/15 09:01 
# Appl: BBEdit
# Task: Copy text from (the beginnging of a document to the first blank line) to the end of document.
# Libs: None
# Osax: None
# Tags: @Applescript, @Script, @BBEdit, @RegEx
# Note: Posted to BBEdit-Talk for <eeo...@gmail.com>.
-------------------------------------------------------------------------------------------

tell application "BBEdit"
    tell front text document's text
        replace "(?ms)(\\A.*?)(?=^$)(.+)" using "\\1\\2\\n-----\\n\\1" options {search mode:grep, case sensitive:false, starting at top:true}
    end tell
end tell

-------------------------------------------------------------------------------------------

Using a Text Factory would be the simplest method, but as you can see the AppleScripted version isn't particularly difficult.

I've added a separator for a visual cue, which you can change as you like.

Now then – let's tackle the task as you describe it via AppleScript but without using the clipboard, since copy and paste is completely unnecessary.

Knowing how to do this may come in handy some time.

-------------------------------------------------------------------------------------------
# Auth: Christopher Stone
# dCre: 2021/08/15 09:01
# dMod: 2021/08/15 09:19
# Appl: BBEdit
# Task: Copy text from (the beginnging of a document to the first blank line) to the end of document.
# Libs: None
# Osax: None
# Tags: @Applescript, @Script, @BBEdit, @RegEx
# Note: Posted to BBEdit-Talk for <eeo...@gmail.com>.
-------------------------------------------------------------------------------------------
property LF : linefeed
-------------------------------------------------------------------------------------------

tell application "BBEdit"

    

    tell front text document's text

        

        set findRecord to find "(?ms)(\\A.*?)(?=^$)" options ¬
            {search mode:grep, case sensitive:false, starting at top:true}

        

        if found of findRecord is true then
            set after it to LF & LF & findRecord's found text
        end if

        

    end tell

    

end tell

-------------------------------------------------------------------------------------------

Doing it this way isn't particularly difficult either, even if it's a little less straightforward.

--
Best Regards,
Chris

e2o

unread,
Aug 16, 2021, 8:37:19 AM8/16/21
to BBEdit Talk
JJ - Thanks so much! Works great! I've gotten great options, and comparing them is going quite illuminating.

Cheeers! - eric

e2o

unread,
Aug 16, 2021, 8:37:30 AM8/16/21
to BBEdit Talk
Patrick - Thanks. Sorry - I'm stumped at to how the threading and quoting works here.
Thanks for the feedback. The need is rather pedestrian - I just create a handful of documents a day with one or more lines of time entries at the beginning. At the end of the day (or week more like), I need to move the individual lines to the end and replace with a single line summary. I just want to eliminate the half dozen clicks and keystrokes 30 times a week.

Thanks as well for the assurance that what seemed like a brute-force method was not necessarily "wrong".

- eric

e2o

unread,
Aug 16, 2021, 8:37:36 AM8/16/21
to BBEdit Talk
Wow, Chris, thanks so much! Both work great. Totally going to pick these apart and learn something. Appreciate it!

- eric

Reply all
Reply to author
Forward
0 new messages