前々回、いろいろなプログラミング言語やファイルフォーマットに対応できるメタプラグイン「vim-polyglot」を紹介し、前回はvim-polyglotによってインストールされるCSVフォーマット用のプラグイン「chrisbra/csv.vim」について取り上げた。その際にも述べたように、chrisbra/csv.vimはあまりにも便利な多機能プラグインなので、今回から数回に渡ってはこのプラグインについて掘り下げたい。
chrisbra/csv.vimでできることは前回一覧で掲載した通りだ。この機能一覧を大きく仕分けると、chrisbra/csv.vimでは次のような操作を行うことができることになる。
- CSVデータの閲覧
- CSVデータ内の移動
- CSVデータの編集
- CSVデータの分析
- CSVデータの比較
- CSVデータの変換
このうち、今回はCSVデータの閲覧に関する機能を取り上げる。これらの機能を知っているのと知っていないのとでは、CSVファイルの扱いやすさがかなり変わってくるはずだ。いきなり全部覚えることは難しいので、使用頻度が高い機能から随時覚えてもらえればと思う。
CSVをテーブル形式で表示
CSVファイル向けの設定を何も行っていない場合、VimでCSVファイルを開くと次のように表示される。ただのテキストファイルだ。
通常、折り返しの設定になっていると思うので、1行が長いCSVデータは折り返しが入ってかなり見にくい(CSVデータは郵便局が公開しているデータ「郵便番号データダウンロード 住所の郵便番号(ローマ字) zip形式 - 日本郵便」のうち、東京都のものを使っている)。
chrisbra/csv.vimを有効にしたVimでこのファイルを開くと次のようになる。
カンマはパイプ区切りになり、それぞれ色付けられている。行は折り返さなくなり、CSVデータとしては閲覧しやすい状態になる。
スプレッドシートアプリケーションにおいて、通常セルは縦横の線が揃った表形式になっている。chrisbra/csv.vimでは「CSVArrangeColumn」というコマンドにこの表示へ切り替える機能が実装されている。つまり、「:%CSVArrangeColumn」のように実行すれば、ファイル全体を縦横が揃った表形式に変換することができる。スプレッドシートに慣れている場合、この表示はなじみやすいだろう。
chrisbra/csv.vimにはもう一つ、表形式表示機能が用意されている。編集中のウィンドウはそのままに、表形式に整えた状態をプレビューとして別のウィンドウに開くというものだ。同機能はCSVTabularizeコマンドに実装されており、「:%CSVTabularize」でファイル全体をテーブル形式でプレビュー表示させることができる。
どちらの機能も1行だけ実施することも、選択した行に対しても実施することができる。
ただし、この2つの機能はある程度実験的な機能だと思っておいたほうがよい。いくつかの機能はchrisbra/csv.vimのほかの機能との連動がうまくいかないからだ。基本的には、あくまでも閲覧するときに使うもの、と考えておくとよいだろう。編集機能などを組み合わせてデータを保存すると困った事態に陥ることがあるので、あまりお薦めできない。この2つの機能は閲覧専用と覚えておきたい。
列をハイライト
デフォルトの表示(表形式表示ではない場合)だと、上下の行のどの部分が同じ列なのかわかりにくい。この場合、CSVHiColumnコマンドで列をハイライト表示させることができる。
「:CSVHiColumn!」でハイライト表示を取り消すことができる。以降のコマンドにおいても共通していることが多いのだが、コマンドに続けて「!(エクスクラメーション)」を書いておくと、その機能が無効化される。また、引数として列番号を指定できることが多く、列番号を指定した場合にはその列に対して処理が行われる。列番号が指定されていない場合には、カーソルのある列が処理の対象となることが多い。
ヘッダ行を固定表示
スプレッドシートでは、1行目を固定表示して使うケースもよくあるだろう。例えば、1行目がヘッダ(項目名)になっているため常に表示しておきたい、といった場合だ。chrisbra/csv.vimでは、「CSVHeader」で同じことができる。
「:CSVHeader」を実行すると、上部に別ウィンドウが開き、そこに1行目が固定表示されるようになる。CSVHeaderに行数を指定すると、その行数分が固定表示の対象となる。
ヘッダ列目を固定表示
CSVHeaderの列版となるコマンドが「CSVVHeader」だ。1列目を常に表示しておきたい場合にはこのコマンドを使用することになる。
CSVHeaderやCSVVHeaderを使用すれば、ヘッダ部分を常に表示させておくことができる。閲覧しやすさがぐっと向上するはずだ。
列でソート
スプレッドシートアプリケーションを操作していると、特定の列の値でデータをソートしたいこともあるだろう。これは、「:CSVSort」で実施できる。
この機能も、ぜひ使い方をマスターしておきたい。
列で検索
Vimの検索機能が強力であることはこれまで何度も取り上げているが、chrisbra/csv.vimではこの検索を特定の列に対して行うことができる。「CSVSearchInColumn」がそのコマンドだ。
この機能も便利なので、ぜひ覚えておいてほしい。
列を折りたたみ
Vimはテキストの折りたたみ機能を提供している。折りたたみたい範囲を選択してから「zf」で実施できる。この機能を使用すると、閲覧したい行だけを表示させておくことができるので便利だ。chrisbra/csv.vimではこれを列に対して実施できる。Vimが折りたためるのは基本的に行単位なので、chrisbra/csv.vimの機能で列単位に折りたたむわけだ。
列単位での折りたたみはCSVVertFoldコマンドで実施する。1列目からカレント列までが折りたたみの対象となる。引数に列番号を指定すれば、1列目から指定した列までを折りたたむことができる。1列目から特定の列までがタグ的なデータになっていて比較時に読む必要がないことなどがあり、そういった場合にCSVVertFoldコマンドで折りたたんでおくと読みやすくなる。
CSVを転置する
表を扱っていると、縦と横の項目を入れ替えたいときがある。こうした処理は通常「転置」と呼ばれる。chrisbra/csv.vimでは、この転置をCSVTransposeコマンドで行うことができる。
転置は、ユーザーによっては喉から手が出るほど欲しい、必須の機能であるはずだ。転置のためだけに、chrisbra/csv.vimを使うというのもアリだろう。
chrisbra/csv.vimのコマンド体系ほか
ここまでのコマンドでお気づきかと思うが、chrisbra/csv.vimのコマンドは「CSV○○ 列番号」のような規則になっている。列番号の指定がなければカーソルがあるカレント列が処理の対象となる。また、「:CSV○○!」でその機能を無効化するという仕組みにもなっている(一部例外はある)。
コマンド名が長くて冗長に思えるかもしれないが、chrisbra/csv.vimのコマンド名は意外と覚えやすい。また、CSVを省略して入力することもできるし、コマンド名は途中まででも使用できる。使っていけばどこまで省略可能なのかもわかってくるだろう。思いの外、短い入力で処理が行えることに気づくはずだ。
処理速度は対象とするCSVファイルのサイズと、PCの性能に強く依存している。当然ながら高速なPCを使っていれば大きなサイズのファイルも快適に編集できる。一方、仮想環境やクラウド上のサーバなどスペックが限定されている環境だと、それなりの遅さになってくる。この辺りは、お使いの環境によるとしか言えない。
CSVデータをVimで閲覧することに最初は違和感を覚えるかもしれない。だが、慣れてくるとスプレッドシートアプリケーションを起動するよりも、こちらで処理するほうが手っ取り早くなるはずだ。ぜひとも、”将来の手抜き”のために今練習して覚えてしまってほしい。
本連載で使っている設定ファイル
本連載で使っている設定ファイル(~/.vimrc)は以下の通りだ。
"dein Scripts=============================
if &compatible
set nocompatible " Be iMproved
endif
" Required:
set runtimepath+=~/.cache/dein/./repos/github.com/Shougo/dein.vim
" Required:
if dein#load_state('~/.cache/dein/.')
call dein#begin('~/.cache/dein/.')
" Let dein manage dein
" Required:
call dein#add('~/.cache/dein/./repos/github.com/Shougo/dein.vim')
" Add or remove your plugins here
call dein#add('junegunn/seoul256.vim')
call dein#add('vim-airline/vim-airline')
call dein#add('vim-airline/vim-airline-themes')
call dein#add('preservim/nerdtree')
call dein#add('tpope/vim-commentary')
call dein#add('tpope/vim-fugitive')
call dein#add('fholgado/minibufexpl.vim')
call dein#add('dense-analysis/ale')
call dein#add('junegunn/fzf', {'build': './install --all'})
call dein#add('junegunn/fzf.vim')
call dein#add('sheerun/vim-polyglot')
" Required:
call dein#end()
call dein#save_state()
endif
" Required:
filetype plugin indent on
syntax enable
" If you want to install not installed plugins on startup.
if dein#check_install()
call dein#install()
endif
" seoul256
let g:seoul256_background = 233
colo seoul256
" vim-airline
let g:airline_powerline_fonts = 1
let g:airline_theme = 'molokai'
" NERDTree
" <C-o> open NERDTree
nnoremap <silent> <C-o> :NERDTreeToggle<CR>
" minibufexpl
nnoremap <silent> bn :<C-u>:bnext<CR>
nnoremap <silent> b1 :<C-u>:b1<CR>
nnoremap <silent> b2 :<C-u>:b2<CR>
nnoremap <silent> b3 :<C-u>:b3<CR>
nnoremap <silent> b4 :<C-u>:b4<CR>
nnoremap <silent> b5 :<C-u>:b5<CR>
nnoremap <silent> b6 :<C-u>:b6<CR>
nnoremap <silent> b7 :<C-u>:b7<CR>
nnoremap <silent> b8 :<C-u>:b8<CR>
nnoremap <silent> b9 :<C-u>:b9<CR>
" fzf
nnoremap <silent> fzf :Files<CR>
nnoremap <silent> ls :Buffers<CR>
"End dein Scripts=========================
set number
syntax on
set whichwrap=b,s,[,],<,>,~,h,l
set cursorline
set incsearch
set hlsearch
set ignorecase
付録 chrisbra/csv.vim が提供する代表的な機能
| コマンド | 内容 |
|---|---|
| CSVWhatColumn | カーソルが何列目にあるか |
| CSVWhatColumn! | 同列1行目の内容を表示 |
| CSVNrColumns | 最大列数を表示(先頭から10行で判断) |
| CSVSearchInColumn /パターン/ | 現在の列をパターンで検索 |
| CSVSearchInColumn 列番号 /パターン/ | 指定した列をパターンで検索 |
| CSVHiColumn | 現在の列を強調表示 |
| CSVHiColumn 列番号 | 指定した列を強調表示 |
| CSVHiColumn! | 列の強調表示を解除 |
| CSVArrangeColumn | テーブル形式での表示へ切り替え(実験的機能) |
| CSVTabularize | テーブル形式でのプレビュー表示 |
| CSVDeleteColumn | 現在の列を削除 |
| CSVDeleteColumn 列番号 | 指定した列を削除 |
| CSVHeader | 1行目を別ウィンドウで表示 |
| CSVHeader 行数 | 先頭から指定行数分を別ウィンドウで表示 |
| CSVHeader! | 開いた行ヘッダウィンドウを閉じる |
| CSVVHeader | 1列目を別ウィンドウで表示 |
| CSVVHeader 列番号 | 行頭から指定列数分を別ウィンドウで表示 |
| CSVVHeader | 開いた列ヘッダウィンドウを閉じる |
| CSVSort | 現在の列でファイルをソート |
| CSVSort 列番号 | 現在の列でファイルをソート |
| CSVSort! | 現在の列でファイルを逆順にソート |
| CSVSort! 列番号 | 現在の列でファイルを逆順にソート |
| CSVColumn | 現在の列をコピー |
| 列番号CSVColumn | 指定した列をコピー |
| CSVMoveColumnor | 現在の列を最後の列の右側へ移動 |
| CSVMoveColumn 列番号 列番号 | 最初に指定した列を、2つ目に指定した列の右側へ移動 |
| CSVSumCol | 現在の列の合計を出力 |
| CSVSumCol 列番号 | 指定した列の合計を出力 |
| CSVSumRow | 行の合計を出力 |
| CSVNewRecord | 新しい行を作成 |
| CSVNewDelimiter デリミタ | 区切り文字を変更 |
| CSVConvertData | データをほかの形式に変換 |
| CSVDuplicates 列番号 | 指定した列で重複している行を出力 |
| CSVAnalyze | 現在の列を分析する(値とその数、割合など) |
| CSVAnalyze 列番号 | 指定した列を分析する(値とその数、割合など) |
| CSVVertFold | 1列目から現在の列を折りたたむ |
| CSVVertFold 列番号 | 1列目から指定した列までを折りたたむ |
| CSVVertFold! | 列の折りたたみを解除する |
| CSVTranspose | 列と行を入れ替える(転置) |
| CSVAddColumn | 現在の列の右側に新しい列を追加 |
| CSVAddColumn 列番号 | 指定した列の右側に新しい列を追加 |
| CSVDupColumn | 現在の列を右側に複製 |
| CSVDupColumn 列番号 | 指定した列を右側に複製 |
| CSVSubstitute 列番号/パターン/文字列/ | 指定した列で置換 |
| CSVColumnWidth | 列ごとの最大文字数を出力 |
| CSVCountCol | 現在の列内の値の数を出力 |
| CSVCountCol 列番号 | 指定した列内の値の数を出力 |
| CSVMaxCol | 現在の列内の最大値を出力 |
| CSVMaxCol 列番号 | 指定した列内の最大値を出力 |
| CSVMaxMin | 現在の列内の最小値を出力 |
| CSVMaxMin 列番号 | 指定した列内の最小値を出力 |
| CSVAvgCol | 現在の列内のデータの平均値を出力 |
| CSVAvgCol 列番号 | 指定した列内のデータの平均値を出力 |
| PopVarCol | 現在の列の母集団分散を出力 |
| PopVarCol 列番号 | 指定した列の母集団分散を出力 |
| SmplVarCol | 現在の列の標本分散を出力 |
| SmplVarCol 列番号 | 指定した列の標本分散を出力 |
| PopStdCol | 現在の列の母標準偏差を出力 |
| PopStdCol 列番号 | 指定した列の母標準偏差を出力 |
| SmplStdCol | 現在の列の標本標準偏差を出力 |
| SmplStdCol 列番号 | 指定した列の標本標準偏差を出力 |
| 移動キー | 内容 |
|---|---|
| 「Ctrl」+「→」 | 次の列へ移動 |
| L | 次の列へ移動 |
| W | 次の列へ移動 |
| 「Ctrl」+「←」 | 前の列へ移動 |
| E | 前の列へ移動 |
| H | 前の列へ移動 |
| ↑ | 列を上へ移動 |
| K | 列を上へ移動 |
| ↓ | 列を下へ移動 |
| J | 列を下へ移動 |
| キー | 内容 |
|---|---|
| ↩️ | 現在の列と一致しないすべての行を動的に折りたたむ |
| Space | 現在の列と一致するすべての行を動的に折りたたむ |
| BS | 動的フィルタから最後のアイテムを削除 |
| 設定項目 | 内容 |
|---|---|
| g:csv_delim | デフォルトのデリミタ |
| g:csv_no_conceal | 1に設定するとデリミタ部分を|で視覚的に表示(デフォルトは設定されていない) |
| g:csv_highlight_column | ‘y’に設定するとカーソルがある列を自動でハイライト |
| b:csv_headerline | ヘッダの行数を指定。0を指定するとヘッダとしてのハイライトが行われなくなる |











