vimの検索と置換
目標
vimの中でログファイルをフィルタリングして置換する作業をexコマンドで行い、そのコマンドをファイルとして残して、再現可能にします。素材は/opt/lab/data/app.log(480行)で、形式はIP 날짜 메서드 경로 상태코드 [ERROR]です(韓国語の語は、順に「日付」「メソッド」「パス」「ステータスコード」を意味します)。
なぜ重要なのか
exコマンドはすべて、範囲 + 動作の構造です。:%s/.../.../g、:5,20s/...、:'<,'>s/...は、同じルールの3つの例です。ここに、行フィルターの:g(パターンに一致する行)と:v(一致しない行)が加わると、ログ加工の大部分が済みます。特に注意すべきは、gフラグを外すと、行ごとに最初のマッチだけが置換される点と、:gと:vがちょうど反対である点です。この2つが、静かに間違った結果を生む代表的な原因です。
ステップ
/root/vimpディレクトリで作業します。.exファイルには編集コマンドだけを入れ、保存・終了コマンドは入れないでください。
/opt/lab/data/app.logを/root/vimp/work.logにコピーしてください。/api/payを含む行が何行あるかを数えて、数字だけを/root/vimp/count.txtに書いてください。- ステータスコードが
500の最後の行の行番号を、/root/vimp/last500.txtに書いてください。 - IPの最後のオクテットを
xxxに置換するコマンドを/root/vimp/mask.exに、その結果を/root/vimp/masked.logに保存してください(10.1.2.3は10.1.2.xxxになります)。 ERRORがない行を削除するコマンドを/root/vimp/errors.exに、結果を/root/vimp/errors_only.logに保存してください。- 行末が
200の行だけを削除するコマンドを/root/vimp/drop200.exに、結果を/root/vimp/no200.logに保存してください。 - 2番目のフィールド(日付)を削除するコマンドを
/root/vimp/nodate.exに、結果を/root/vimp/nodate.logに保存してください。 - 上の3つをすべて適用するコマンドを
/root/vimp/report.exに入れて、結果を/root/vimp/report.logに保存してください。最終的な形は10.1.2.xxx GET /api/item 500 ERRORです。
参考
:%s/패턴//gn(韓国語の語は「パターン」という意味です)は、何も変更せず、マッチの個数だけを教えてくれます。置換前の影響範囲の確認用です。- 後方参照は、括弧で囲んだ部分を呼び戻す文法で、マッチ全体は
&です。 - 採点ツールは、
.exファイルを元のファイルのコピーにもう一度適用して、結果ファイルと一致するかを確認します。 - よくあるミス1: ステップ5で
:gを使うと、正反対の結果になります。 - よくあるミス2: ステップ6で
:g/200/dのように書くと、IPやほかのフィールドに200を含む行まで消えます。
作業用のコピーを作る
/opt/lab/data/app.logを/root/vimp/work.logにコピーしてください。
元のファイルは読み取り専用のままにして、コピーで作業するのが基本です。
マッチの個数だけを数える
/api/payを含む行が何行あるかを数えて、数字だけを/root/vimp/count.txtに書いてください。
置換コマンドにnフラグを付けると、置換せずに個数だけを教えてくれます。スラッシュを含むパターンには、エスケープが必要です。
最後の500応答を探す
ステータスコードが500の最後の行の行番号を、/root/vimp/last500.txtに書いてください。
Gでファイルの末尾に移動してから、?で逆方向に検索します。現在の行番号は、Ctrl-Gや:set numberで確認できます。
IPマスキングの置換
IPの最後のオクテットをxxxに置換するコマンドを/root/vimp/mask.exに、その結果を/root/vimp/masked.logに保存してください(10.1.2.3は10.1.2.xxxになります)。
残す部分を括弧で囲んで、後方参照で呼び戻します。最後のオクテットだけが変わる必要があります。
ERROR行だけを残す
ERRORがない行を削除するコマンドを/root/vimp/errors.exに、結果を/root/vimp/errors_only.logに保存してください。
:gと:vは反対です。ない行を削除するのはどちらか、考えてみてください。
正常応答を除去する
行末が200の行だけを削除するコマンドを/root/vimp/drop200.exに、結果を/root/vimp/no200.logに保存してください。
行末の固定を忘れると、ほかのフィールドに含まれる200まで一致します。
日付の列を削除する
2番目のフィールド(日付)を削除するコマンドを/root/vimp/nodate.exに、結果を/root/vimp/nodate.logに保存してください。
最初の2つのフィールドをまとめて捕捉し、1つ目だけを復活させると、2つ目が消えます。
3段階の変換を1つのスクリプトにまとめる
上の3つをすべて適用するコマンドを/root/vimp/report.exに入れて、結果を/root/vimp/report.logに保存してください。最終的な形は10.1.2.xxx GET /api/item 500 ERRORです。
前で作った3つのコマンドを、順に入れればよいです。順序によって結果が変わることがあるので、確認してください。