vimのマクロとレジスタ
目標
マクロとは何か、つまりレジスターに入った単なるテキストであることを直接確認し、繰り返し可能なマクロを設計する方法を身に付けます。
なぜ重要なのか
qaで記録したマクロは、キー入力が文字列そのままレジスターaに保存されたものです。yankとマクロが同じa–zの領域を使うのも、そのためです。この事実を知っていれば、マクロをファイルとして取り出して編集し、また入れることができ、ラボのようにファイルとして提出して検証することもできます。そして、繰り返し可能なマクロには設計原則があります。開始点を絶対的に固定し、移動は内容を基準に行い、最後に次の対象へ移ります。この3つのうち1つでも欠けると、2行目からずれます。
ステップ
/root/vmacディレクトリで作業します。マクロファイルには、キー入力を1行で書きます。
/root/vmac/list.txtに次の6行を入れてください。web01/web02/db01/db02/cache01/queue01- 各行を
- web01のようにするマクロのキー入力を/root/vmac/macro1.txtに、適用結果を/root/vmac/bulleted.txtに保存してください。 - 各行を
"web01",にするマクロを/root/vmac/macro2.txtに、結果を/root/vmac/quoted.txtに保存してください。このマクロには、ESC文字が必ず入っている必要があります。 - 各行の前に
1.、2.のように行番号を付けるexコマンドを/root/vmac/number.exに、結果を/root/vmac/numbered.txtに保存してください。 /root/vmac/hosts.txtに次の6行を入れてください。web01.prod.example.com/web02.staging.example.com/db01.prod.example.com/db02.staging.example.com/cache01.prod.example.com/queue01.staging.example.comそして、stagingを含む行にだけ先頭に#を付けるコマンドを/root/vmac/onlystaging.exに、結果を/root/vmac/staging.txtに保存してください。hosts.txtからprodを含む行だけを集めて、ファイルの末尾に追記する(合計9行)コマンドを/root/vmac/collect.exに、結果を/root/vmac/collected.txtに保存してください。/root/vmac/table.txtに次の5行を入れてください。name=web01/role=frontend/zone=seoul/port=8080/tier=gold各行をNAME:web01のように、キーは大文字に、等号はコロンに変換するマクロを/root/vmac/macro3.txtに、結果を/root/vmac/table_out.txtに保存してください。hosts.txtからprodの行だけを残し、先頭に-、末尾に:80を付けるコマンドを/root/vmac/final.exに、結果を/root/vmac/final.txtに保存してください。
参考
- 採点ツールは、マクロファイルの1行目をレジスターに入れて、
:%normal @qですべての行に適用してみます。 :normalで実行される挿入モードは、コマンドが終わるときに自動的に終了するので、最後が挿入のマクロには、ESCがなくてもかまいません。途中で挿入を終える必要があるときだけ必要です。:reg aで、レジスターの内容を目で確認できます。- よくあるミス1: ステップ2のマクロの末尾のスペースが、保存の過程で切り落とされると、結果が
-web01になります。 - よくあるミス2: ステップ6で小文字のレジスターを使うと、毎回上書きされて、最後の1行だけが残ります。
練習用のリストを作る
/root/vmac/list.txtに次の6行を入れてください。
web01 / web02 / db01 / db02 / cache01 / queue01
6行ちょうどです。順序も合わせる必要があります。
最初のマクロ: 箇条書きの記号を付ける
各行を- web01のようにするマクロのキー入力を/root/vmac/macro1.txtに、適用結果を/root/vmac/bulleted.txtに保存してください。
Iは、行頭から入力を始めます。マクロの最後のスペース1つまで、ファイルにそのまま保存される必要があります。
マクロにESC文字を入れる
各行を"web01",にするマクロを/root/vmac/macro2.txtに、結果を/root/vmac/quoted.txtに保存してください。このマクロには、ESC文字が必ず入っている必要があります。
挿入モードから抜けるキーも、マクロの一部です。vimでCtrl-Vを押してからEscを押すと、その文字がファイルに入ります。
行番号を付ける
各行の前に1. 、2. のように行番号を付けるexコマンドを/root/vmac/number.exに、結果を/root/vmac/numbered.txtに保存してください。
行ごとに値が変わるので、固定の文字列ではできません。置換の置き換え側で、式(expression)を評価させる文法があります。
条件に合う行にだけ適用する
/root/vmac/hosts.txtに次の6行を入れてください。
web01.prod.example.com / web02.staging.example.com / db01.prod.example.com / db02.staging.example.com / cache01.prod.example.com / queue01.staging.example.com
そして、stagingを含む行にだけ先頭に# を付けるコマンドを/root/vmac/onlystaging.exに、結果を/root/vmac/staging.txtに保存してください。
:g/パターン/normalのあとにキー入力を続ける形で、行フィルターとNormalモードのキーを結合します。
散らばった行を1か所に集める
hosts.txtからprodを含む行だけを集めて、ファイルの末尾に追記する(合計9行)コマンドを/root/vmac/collect.exに、結果を/root/vmac/collected.txtに保存してください。
小文字のレジスターは上書きし、大文字のレジスターは追記します。集めたあと、ファイルの末尾に貼り付けてください。
2つの動作をまとめたマクロ
/root/vmac/table.txtに次の5行を入れてください。
name=web01 / role=frontend / zone=seoul / port=8080 / tier=gold
各行をNAME:web01のように、キーは大文字に、等号はコロンに変換するマクロを/root/vmac/macro3.txtに、結果を/root/vmac/table_out.txtに保存してください。
テキストオブジェクトで単語を1つ大文字に変換し、文字検索と1文字の置換をつなげます。
フィルター + 接頭辞 + 接尾辞の総合
hosts.txtからprodの行だけを残し、先頭に- 、末尾に:80を付けるコマンドを/root/vmac/final.exに、結果を/root/vmac/final.txtに保存してください。
前で使った手法を、順に組み合わせてください。残す行を先に選ぶのが、順序として有利です。