2012の283日目の記事です。最近レビュー記事を書くプレッシャーからの現実逃避にSQLの練習をやっていました。テーブルのデータを生成する時にVimを少しだけ使ったので、今日はその時のことを書きます。2012のページの表からVimのバッファにコピペします。Values)形式が便利です。その名の通りタブ文字で各項目/各セルが区切られたテキストです。Firefoxだと表をCtrl+マウスドラッグでコピペするとTSV形式のテキストがコピペできます。ChromeだとCtrlを押さなくてもTSV形式になりました。IEだとスペース区切りになってしまいました。スペースは普通の文字列に頻出するのでこれではあまりうれしくありませんね。FirefoxかChromeを使ってください。ちなみに今回tableタグからVimのバッファにコピペするのにTSV形式を使いましたが、逆もいけます。なんらかの手段でTSV形式のテキストを生成してコピーすればExcelファイルに貼り付ける事ができます。Excelを使わなければいけないお仕事で地味に役立ちます。*1ちなみにコピーしたテキストをVimのバッファにペーストする時は、中クリックでもいけます。(この時Vimのバッファは空の状態)Vimのバッファにペーストするという手順を踏むため、マウスから手を離してペーストするより中クリックでペーストしてしまった方が速いです。編集してINSERT文を生成しようtableタグからコピペしたら、Vimのバッファは以下のような状態になっているはずです。使用したコード補完を行う278(タブ文字)09/04(水)(タブ文字)@KSuzukiii(タブ文字)ファイルに保存する。(:sav[eas])この状態からINSERT文を生成していきましょう。そのためにはまずどのようなテーブルにどのような項目をINSERTするのか決めるために、DDLを決めておきます。DDLは以下の通りです。さっきのTSV形式のテキストと同じく4項目ですし、項目を追加する必要はなさそうですね。いうことは各項目をINSERTできるSQLの値に編集するだけでよさそうです。各項目を文字列化まずは文字列として扱うため、各項目を「'(シングルクォート)」で囲みましょう。:%s/[^\t]\+/'&'/g「&(アンパサンド)」はマッチした文字列を意味します。括弧*2でくくるよりこちらの方がタイプ数も少なくて楽です。今度は左から順番に編集していきましょう。nthはint型なので先程つけたシングルクォートは不要ですので取ります。Serverでは先頭0の数値を8進数として解釈する事はないようですが*3、気持ち悪いので取ってしまいましょう。確認のため検索します。/^'0*\(\d\+\)'これでハイライトされている部分を目視で確認し、一括置換しても構わないか確認します。括弧をつけたのは置換のためです。確認して問題ないようだったら、対象行をヴィジュアルモードで選択したのち以下を実行して置換します。:'<,'>s//\1/このようにパターンを省略すると「/」レジスタの内容(=前回検索したパターン)が使われます。ちなみに1行につき1個だけなので、gフラグは付けなくても結構です。「12/01(土)」→「2012/12/01」のように編集する必要があります。1月以降は2013年なので「09/01(日)」→「2013/09/01」のように編集します。先に数の少ない12月から手を付けましょう。前回と同じく確認してから一括置換します。12月の各日付に2012年を付加し、曜日を削除します。/\(12\/\d\+\)([土日月火水木金]):'<,'>s//2012\/\1/次に1月以降の各日付を編集します。゙ーッ」という感じになってきたら、おもむろにコマンドラインでを押してコマンドラインウインドウに移り正規表現を組み立てた方が楽です。ちなみにコマンドラインウインドウでは過去の履歴もyyGpでコピペできます。今回は「/」レジスタからパターンをコピペするのと2012を2013に変えるだけだったので、私はコマンドラインで済ませました。無駄なので「@tyru」→「tyru」のように先頭の@を取ります。インサートモード編」がひっかかることから、ユーザ名だけにヒットする正規表現を組み立てる必要があることが分かりました*4。便利な「\zs」と「\ze」を使います。何度か書いているのでそちらを参照してください。/'\zs@\ze\w\+'これでユーザ名の前の「@」だけにマッチします。あとは前回と同じく:'<,'>s///で一括削除です。title(記事名)は今回特に編集しません。タブ文字をカンマに置き換えるINSERTの項目に変換するため、タブ文字をカンマに置き換えます。(まずは行頭)ここまで正規表現を使ってきましたが、メタ文字のことを考えるのも面倒なので、私は行頭と行末に挿入するのであればを使います。この段階でバッファの内容は以下のようになっています。公開するまで'行頭でを押してGで最終行まで移動し、Iで挿入する準備*5を始めます。values(」を入力し、で抜ければ全行の行頭に挿入されます。(行末)次は行末です。適当な位置でを押してGで最終行まで移動し、$で行末に移動してIで挿入する準備*6を始めます。「);」を入力してで抜ければ全行の行末に挿入されます。公開するまで');仕上げここまでくればINSERT文は出来上がっているので、DB名を指定すれば完成です。1行目に以下のように挿入します。あと書きいかがでしたでしょうか。普段からVimGolfで鍛えている皆様ならもっと効率の良い方法を思い付くかもしれません。普段対話的に操作するなら、操作している内にVimの独特の操作体系で一種のフロー状態に入っていくので、フローを途切れさせないためにExコマンドを多様したバッチ的な操作よりもあえてノーマルモードのコマンド多めで操作したりしています。後者に対しては、先程言ったように「正規表現(コマンドラインモード)はおまけ。(フロー状態を作り出す)ノーマルモードこそ至高」と答えるでしょう。言い換えればノーマルモードはVimmerの心のホームポジションです。ちなみにもっとデータ量が多い場合、目視での確認を省いて、:g[lobal]コマンドや:s[ubstitute]コマンドでのバッチ処理もできるあたりVimは本当に引き出しが多く、また同時にその引き出しはいくらでも拡張可能なことに驚くばかりです。Vimって本当に素晴らしいエディタですね。*1:仕事中Excelとにらめっこする時間が圧倒的に多いなら、COM経由でWSHスクリプトからExcelを操作するのが一番楽できる近道のような気がします。ノーマルモードに移りたい。便利にした月ごとはてなブログをはじめよう!tyruさんは、はてなブログを使っています。ブログを報告するスターをつけました引用をストックしましたストック一覧を見る閉じる引用するにはまずログインしてくださいログイン閉じる引用をストックできませんでした。再度お試しください閉じる限定公開記事のため引用できません。