|
From: | MBR |
Subject: | Re: Emacs equivalent of the ":g" command in vi |
Date: | Fri, 22 Jul 2011 16:27:44 -0400 |
User-agent: | Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.9.2.17) Gecko/20110414 Thunderbird/3.1.10 |
On 7/22/2011 4:42 AM, C K Kashyap wrote:
Hi, I looked for the same thing ages ago when I switched from vi to emacs. Eventually I figured out that: :g/regular _expression_/operationreflects an 'ed' mindset, and that an Emacs macro with a repeat count is actually far more powerful . (In case you're wondering what 'ed' is, it was the original, line-oriented, Unix editor. 'vi' was Bill Joy's visual mode version of 'ex', which was his enhanced version of 'ed'.) An Emacs macro is a series of emacs commands that you can replay. You use C-( and C-) as follows to create a macro: C-(Then, whenever you type C-x e, Emacs will replay the commands. At this point, you're probably wondering how this can substitute for vi's g//. Simple. Just start your macro off with a regular _expression_ search, do whatever you want, and then replay it multiple times with: C-u count C-x eSpecify a large enough repeat count, and you can make your macro apply to the whole file. For example, to delete each line of a buffer if the line matches a regular _expression_, you'd define the macro with: C-( ;; Begin recording macroThen you'd execute the macro with: C-u 10000 C-x eOf course, there's an easier way to delete lines that match a regular _expression_: M-x delete-matching-linesBut you described the general problem as needing to perform a certain action on each line of a buffer if the line matches a regular _expression_. And the approach of defining a macro to do what you want and then executing it with a large repeat count gives you a general purpose mechanism to do arbitrary operations rather than just delete the line. For example, if I have a file of lines of the format: zip,street address,city,state,phone,nameThat I wanted to rearrange to: name,phone,street address,city,state,zipI could run: M-x replace-regexpwhich is the equivalent of vi's: :g/^\([^,]*\),\([^,]*\),\([^,]*\),\([^,]*\),\([^,]*\),\([^,]*\)$/s//\6,\5,\2,\3,\4,\1/gBut making sure you've got that regular _expression_ right can be tricky. It can be much easier to just do it with emacs commands applied to a single line. Although the following is difficult to read, I think if you try it out you'll find it pretty straightforward. First fill an emacs buffer with lots of lines of the form: name,phone,street address,city,state,zipThen type these emacs keystrokes (omitting the comments): ;; Begin recording macroReplay it 10,000 times with: C-u 10000 C-x eIt will stop as soon as it runs out of matching lines. The point is that the operations you can repeat this way are limited only by your imagination. There's a variant of this that I use frequently. I often find that a non-emacs application wants me to type lots of information into individual fields of an input screen. It's a pain to have to type all that data, especially when I have that data in a text file. In emacs I can organize the data into the same order as the input fields in the application, putting each field's data on a separate line of the emacs buffer. Then I do the following in emacs: ;; Begin recording macroOnce I've defined that macro, I can repeatedly type: ;; This is not an Emacs command. It tells the window managerAt that point, I repeatedly type: C-x e ALT-TAB C-v TAB ALT-TABWhile it's not fully automated, If I've got lots of data that has to be entered through a GUI interface, it makes things go a whole lot faster. If you should want to save a macro you've created this way so you can use it in future Emacs sessions: Open your .emacs file: C-x C-f ~/.emacs P.S. - Interesting side-note. Did you know that the ed command:Mark Rosenthal g/regular _expression_/operation is where the name "grep" came from? In ed and ex, the "g" means do a global search for the immediately following regular _expression_, and apply the operation to every matching line. One such operation is "p" meaning "print". Using "re" as shorthand for "regular _expression_", the ed command to print every line that matches a particular regular _expression_ is: g/re/p |
[Prev in Thread] | Current Thread | [Next in Thread] |