From mboxrd@z Thu Jan 1 00:00:00 1970 Path: news.gmane.org!not-for-mail From: =?ISO-8859-1?Q?Andreas_R=F6hler?= Newsgroups: gmane.emacs.help Subject: Re: Emacs equivalent of the ":g" command in vi Date: Fri, 22 Jul 2011 22:37:04 +0200 Message-ID: <4E29DF70.7080008@easy-emacs.de> References: <4E29DD40.80909@arlsoft.com> NNTP-Posting-Host: lo.gmane.org Mime-Version: 1.0 Content-Type: text/plain; charset=ISO-8859-1; format=flowed Content-Transfer-Encoding: 7bit X-Trace: dough.gmane.org 1311367038 16983 80.91.229.12 (22 Jul 2011 20:37:18 GMT) X-Complaints-To: usenet@dough.gmane.org NNTP-Posting-Date: Fri, 22 Jul 2011 20:37:18 +0000 (UTC) To: help-gnu-emacs@gnu.org Original-X-From: help-gnu-emacs-bounces+geh-help-gnu-emacs=m.gmane.org@gnu.org Fri Jul 22 22:37:14 2011 Return-path: Envelope-to: geh-help-gnu-emacs@m.gmane.org Original-Received: from lists.gnu.org ([140.186.70.17]) by lo.gmane.org with esmtp (Exim 4.69) (envelope-from ) id 1QkMTC-00031B-7f for geh-help-gnu-emacs@m.gmane.org; Fri, 22 Jul 2011 22:37:14 +0200 Original-Received: from localhost ([::1]:54335 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1QkMTB-0002Vu-NZ for geh-help-gnu-emacs@m.gmane.org; Fri, 22 Jul 2011 16:37:13 -0400 Original-Received: from eggs.gnu.org ([140.186.70.92]:51397) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1QkMT7-0002Vi-Ep for help-gnu-emacs@gnu.org; Fri, 22 Jul 2011 16:37:10 -0400 Original-Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1QkMT5-0003J9-Ur for help-gnu-emacs@gnu.org; Fri, 22 Jul 2011 16:37:09 -0400 Original-Received: from moutng.kundenserver.de ([212.227.17.10]:61205) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1QkMT5-0003Ir-Ag for help-gnu-emacs@gnu.org; Fri, 22 Jul 2011 16:37:07 -0400 Original-Received: from [192.168.178.27] (brln-4d0c200f.pool.mediaWays.net [77.12.32.15]) by mrelayeu.kundenserver.de (node=mrbap4) with ESMTP (Nemesis) id 0M4HXH-1RbDwA1mrr-00rn9e; Fri, 22 Jul 2011 22:37:05 +0200 User-Agent: Mozilla/5.0 (X11; U; Linux i686; de; rv:1.9.2.18) Gecko/20110616 SUSE/3.1.11 Thunderbird/3.1.11 In-Reply-To: <4E29DD40.80909@arlsoft.com> X-Provags-ID: V02:K0:ST8rqhunKAQiE/jfu9Ml+zmR4iV4qALXEaQj9y2Nvdk e8Kp0N96sjbcVrLuDFF95ixJxs/dzL09dbPposp1NE4XmSfPj/ iQWZ8HrLojvdXWOxQhpPhGwcCoqRcnPyhVPl6lMXzTlJ2nW51M LRbITIf0DV37MpenBRrpmcltpK7PdgBfmmRr4ryFZiakJoEi8c wUVYb/SXwv6Ln2no5EQONL5FUZeTE1nfXBQgqNwoFQ= X-detected-operating-system: by eggs.gnu.org: Genre and OS details not recognized. X-Received-From: 212.227.17.10 X-BeenThere: help-gnu-emacs@gnu.org X-Mailman-Version: 2.1.14 Precedence: list List-Id: Users list for the GNU Emacs text editor List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: help-gnu-emacs-bounces+geh-help-gnu-emacs=m.gmane.org@gnu.org Original-Sender: help-gnu-emacs-bounces+geh-help-gnu-emacs=m.gmane.org@gnu.org Xref: news.gmane.org gmane.emacs.help:81738 Archived-At: Am 22.07.2011 22:27, schrieb MBR: > On 7/22/2011 4:42 AM, C K Kashyap wrote: >> Hi, >> Could someone please tell me how I could go about something like this - >> I need to perform a certain action (such as delete the line) on each >> line of a buffer if the line matches a regular expression. In vim, we >> can use the :g command for this. >> Regards, >> Kashyap > > I looked for the same thing ages ago when I switched from vi to emacs. > Eventually I figured out that: > > :g/regular expression/operation > > reflects 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-( > type any commands you want Emacs to remember > 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 e > > Specify 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 macro > C-M-s regexp ;; Search for regular expression > C-a ;; Go to beginning of line > C-k ;; Kill one line by typing C-k twice > C-k ;; > C-) ;; End recording macro > > Then you'd execute the macro with: > > C-u 10000 C-x e > > Of course, there's an easier way to delete lines that match a regular > expression: > > M-x delete-matching-lines > > But 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,name > > That I wanted to rearrange to: > > name,phone,street address,city,state,zip > > I could run: > > M-x replace-regexp > ^\([^,]*\),\([^,]*\),\([^,]*\),\([^,]*\),\([^,]*\),\([^,]*\)$ > \6,\5,\2,\3,\4,\1 > > which is the equivalent of vi's: > > :g/^\([^,]*\),\([^,]*\),\([^,]*\),\([^,]*\),\([^,]*\),\([^,]*\)$/s//\6,\5,\2,\3,\4,\1/g > > > But 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,zip > > Then type these emacs keystrokes (omitting the comments): > > ;; Begin recording macro > C-( > ;; Narrow the buffer to the current line: > C-SPC C-n C-x n n M-< > ;; Move the part after the fifth "," > ;; to the beginning of the line > C-s , C-s C-s C-s C-s C-b C-k C-a C-y , C-a C-d > ;; Move the part that's now after the fifth "," > ;; to the second comma-delimited position > C-s , 4*C-s C-b C-k C-a M-f C-y > ;; Move the third comma-delimited part to the end > M-d C-e C-y > ;; Move forward over the newline to the next line > C-f > ;; Widen so you can see the whole buffer > C-x n w > ;; End recording macro > C-) > > Replay it 10,000 times with: > > C-u 10000 C-x e > > It 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 macro > C-( > ;; Mark region from beginning to end of line > C-aC-SPCC-e > ;; Copy region so it can be pasted into another application > C-w > ;; Move forward over the newline to the next line > C-f > ;; End recording macro > C-) > > Once I've defined that macro, I can repeatedly type: > > ;; This is not an Emacs command. It tells the window manager > ;; to give keyboard focus to the other application. > ALT-TAB > ;; Paste into the input field > C-v > ;; Move focus to the next input field > TAB > ;; Give keyboard focus to Emacs. > ALT-TAB > ;; Repeat the macro, which copies the next line. > C-x e > > At that point, I repeatedly type: > > C-x e ALT-TAB C-v TAB ALT-TAB > > While 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 > Give it a name by with:M-x name-last-kbd-macro > Insert it into your .emacs with: M-x insert-kbd-macro > Save your .emacs file: C-x C-s > > Mark Rosenthal > mbr@arlsoft.com > > P.S. - Interesting side-note. Did you know that the ed command: > > 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 > > > Hi, from my feeling: finally much easier then fighting which recorded keyboard-macros is writing it's own little functions. Running them under edebug then and a breakpoint set allows neatly control Keyboard macros are good for really limited and easy repeats. Andreas