Exercise 09 Macros
Exercise 09 Macros
Goal:
Instructions:
First, start a command line session on your local machine. Next, use vim to open the
"macros-practice.txt" file that came in the course downloads. To do that, navigate to the location of
the file. Remember this could be different for you depending on where you extracted the contents of
the file. This example assumes the course download was saved into your Downloads folder and
extracted from there.
cd Downloads
cd vimclass
vim macros-practice.txt
Let's say you have some old Python code (version 2.6 or earlier) that needs to be updated to work
with the new Python interpreter (version 3.0 or later). The print statement was replaced with the
print() function. That means you'll need to change the following line from this:
To this:
Let's do this with a macro. By the way, it's not important to know anything about Python. The goal
here is to give you a practical example for you to practice your Vim macros skills with.
● Place your cursor on the line that reads: print "Macros are very fun!"
http://www.LinuxTrainingAcademy.com
● Start recording into the "a register with qa.
● Normalize your cursor position to the beginning of the line by typing 0.
● Position the cursor at the next space with f<SPACE>.
● Replace the space with an opening parenthesis with r(.
● Append a closing parenthesis to the line with A) and press <ESCAPE> to return to normal
mode.
● Now position the cursor on the next line with j so the macro can be easily repeated.
● Finally type q to stop recording the macro.
You can examine the contents of your macro by looking at the "a register with :reg a<ENTER>.
Here is what it should look like:
"a 0f r(A)^[j
Play your macro on the next line by typing @a. Use @@ to repeat the macro on. Continue repeating
the macro with @@ on the remaining print statements.
NOTE: The solution provided above is not the only way to accomplish this task! One simple
example is replacing f<SPACE> with t" in the macro. Both perform the same act of positioning the
cursor under the space. As long as you get the desired results you're after, that's all that matters.
Let's say you have a list of users and you want to perform the same set of actions on each of those
users. One way to accomplish this is to record a macro that performs the required command for
one user and apply that macro to the rest of the list.
jason
sophia
jack
emma
ava
Into this:
http://www.LinuxTrainingAcademy.com
You could use those commands on a Linux system to lock each of the user accounts and add the
account names to the locked_users.txt file. Of course, it's not important what these commands do
as we're interested in Vim, but I wanted to provide you with a practical example.
You can examine the contents of your macro by looking at the "b register with :reg b<ENTER>.
Here is what it should look like:
Play your macro on the next line by typing @b. You can probably see that there are three more items
in this list, so use 3@b to repeat the macro four times.
Next, create a macro that changes a United States style phone number from:
2798265253
To:
(279) 826-5253
You can examine the contents of your macro by looking at the "p register with :reg p<ENTER>.
Here is what it should look like:
Because there is a long list of phone numbers that scroll off the bottom of your screen you can't
easily know how many times you need to apply the macro. Also, repeating @@ could take quite
awhile. So, get the range you need to apply the macro to. Turn on line numbering with :set
nu<ENTER>. Note that your cursor is currently on line 25. Now page down to the end of the list of
phone numbers with Ctrl-f. You'll find the last phone number is on line 73.
Execute the macro over this range using the normal command. Type :25,73 normal
@p<ENTER>. Now check that the macro was executed over that entire range by paging up with
Ctrl-b.
The next set of lines in the file contain system logs from a Linux server. Specifically these lines are
logs of blocked connection attempts by the local Linux firewall. Your goal is to extract the
timestamp, the source IP address of the connection attempt, and the destination port.
This line:
http://www.LinuxTrainingAcademy.com
Jan 13 09:57:01,190.188.193.152,23
● Place your cursor on the line that starts with "Jan 13 09:57:01".
● Start recording into the "l register with ql.
● Normalize your cursor position to the beginning of the line by typing 0.
● Position your cursor on the space just after the time stamp by typing tw.
● Now delete all the text up to "SRC=". You can do this with dtS.
● Now delete SRC with dw.
● Next, replace "=" with a comma: r,.
● Position the cursor after the IP address with f<SPACE>.
● Delete the text up to "DPT=" with d/DPT<ENTER>.
● Now delete DPT with dw.
● Next, replace "=" with a comma: r,.
● Position the cursor after the port number with f<SPACE>.
● Delete the remaining text on the line with D.
● Now position the cursor on the next line with j so the macro can be easily repeated.
● Finally type q to stop recording the macro.
You can examine the contents of your macro by looking at the "l register with :reg l<ENTER>.
Here is what it should look like:
As always, there are other ways to accomplish the same task. Just one simple example is using
2cw,<ESCAPE> to change "SRC=" to "," instead of using dwr,. Take a moment and think of other
ways to alter this macro and get the same result.
Test your macro on the next line by typing @l. If it looks correct, continue with @@ until all the lines
are in the desired format.
Remember that macros are just a series of recorded keystrokes. Even though you've been working
on macros that manipulate single lines, you can as easily manipulate multiple lines. Let's say you
want to turn these three lines into one line.
Before:
http://www.LinuxTrainingAcademy.com
Country China
1,380,950,000 people
After:
1,380,950,000;China
You can examine the contents of your macro by looking at the "c register with :reg c<ENTER>.
Here is what it should look like:
"c 0dwjdWkPr;j2dd
Now use a count to repeat the macro 4 more times to format the rest of the data in this set. Type
4@c.
As always, there are multiple ways to achieve the same result in Vim.
http://www.LinuxTrainingAcademy.com
The goal is convert those links to the following:
armyspy.com
cuvox.de
dayrep.com
einrot.com
fleckens.hu
gustr.com
jourrapide.com
rhyta.com
superrito.com
teleworm.us
● Place your cursor at the beginning of the line that starts with "<a".
● Start recording into the "q register with qq.
● Delete the text up to and including "@" with df@.
● Position the cursor under the "<" with f<.
● Replace "</a>" with <ENTER> by typing cf><ENTER><ESCAPE>.
● Finally type q to stop recording the macro.
You can examine the contents of your macro by looking at the "q register with :reg q<ENTER>.
Here is what it should look like:
"q df@f<cf>^M^[
Execute the macro with @q. Keep repeating the macro with @@ until you are left with the desired
text.
If you want to abandon your changes so you can try this practice exercise again, use :q!<ENTER>.
http://www.LinuxTrainingAcademy.com