CSVはよく使われるデータ形式だが、この形式がデータ交換用データの全てというわけではない。データ交換という観点から言えば最近ではJSONが使われることが多いし、XMLも多い。閲覧という観点から言えばやはりHTMLが使われることが多く、CSVデータが閲覧用にそのまま提供されるというのは少ないように思う。
CSVはデータ形式がシンプルなものなので、プログラムを使って別の形式に変換するというのがさほど難しくない。自分で厳密にCSVパーサを実装しようと思うと多少難しくなるが、CSVパーサはすでにさまざまなものが提供されているし、サードパーティ製ライブラリを使うのが面倒、または使い方がよくわからないという場合でも、簡単なスクリプトでもある程度の変換は自動で行うことができる。ただし、プログラミングをしたことがない方にとってはハードルが高いかもしれない。
そこでchrisbra/csv.vimだ。このプラグインにはCSVデータを任意のほかのフォーマットに変換するための機能が用意されている。簡単な形式であれば、この機能だけで十分だ。プログラミングが面倒だとか、やったことがない、という方にとって、この機能はかなり便利なのではないかと思う。今回はこの機能の使い方を紹介する。
CSVConvertDataでデータ変換 - HTMLへ変換
chrisbra/csv.vimには「CSVConvertData」という機能が用意されている。この機能はレコード(行)単位でCSVデータを任意のテキストデータへ変換するというものだ。全データの最初と最後に任意の文字列を付加することができ、結果としてほかのフォーマットへの変換が行われることになる。
例えば、次のCSVデータをHTMLへ変換する例を考える。
CSVConvertDataを実行する。
CSVConvertDataを実行すると、次のように「Pre convert text: 」というプロンプトが表示される。全データの最初に付与する文字列を指定せよ、という意味だ。
HTMLのテーブルデータに変換しようと思うので、ここで次のように「<html><body><table>」と入力する。変換後全データの先頭にこの文字列が追加されることになる。
次は逆に全データ変換後に最後に付与する文字列の入力を次のように求められる。
テーブルとHTMLを閉じたいので、先程入力したタグに対応する終了タグ「</table></body></html>」と入力する。
変換としてはここからが本題だ。次のように、各レコード(各行)をどのような文字列へ変換するのか指定するモードになる。
ここでは「<tr><td>%s</td><td>%s %s %s</td></tr>」と入力する。ポイントは「%s」だ。この文字列はセルの値に置換される。1つ目の%sは1列目の値へ、2つ目の「%s」は2列目の値へ、といった感じだ。つまり、使いたいデータを1列目から順番に並べておく必要がある。列の移動に関してはこれまでに操作方法を説明してあるので、その操作で入れ替えを行って操作してもらえればと思う。
変換を実施すると、次のように変換後のデータが別ウィンドウで表示される。プログラムを組むことなくここまでできるのだから簡単なものだ。
ただし、上記スクリーンショットからわかるとおり、この方法だとデリミタ(区切り文字)も含まれているほか、ダブルクォーテーションも含まれていて、閲覧用データとしては扱いにくい。もうちょっと実用的なデータに変換していこう。
CSVConvertData!でデータ変換 HTMLへ変換
CSVConvertDataにはビックリマークを指定した「CSVConvertData!」というバージョンが用意されている。CSVConvertData!はデリミタを変換後データに含めないというもので、用途によってはこちらのほうが便利ではないかと思う。
まず、Vimの置換機能を使ってダブルクォーテーションを削除する。
CSVConvertData!を実行する。
先ほどと同じようにPre、Post、変換内容を指定する。
生成されるHTMLデータは次のようになる。最初に変換した内容よりも実用的な形式になっていることがわかる。
Webブラウザで閲覧すると次のようになる。シンプルだが見える形式には仕上がっていることがわかる。
このように簡単なデータ変換であればCSVConvertData!を使って実施できる。CSVConvertData!の使い方がすでに簡単なスクリプトというかプログラミングとも言える。プログラミングをしたことがない方は、こういった作業を通じてプログラミングに慣れていくとよいだろう。
chrisbra/csv.vimのポテンシャルの高さ
プラグインのメタプラグイン経由でインストールしたchrisbra/csv.vimだが、このプラグインのポテンシャルの高さは伝わったのではないだろうか。閲覧から編集、分析、フィルタリング、データ変換まで、chrisbra/csv.vimを使うことでさまざまな操作を実地することができる。
CSVデータのような形式のデータをVimで操作することができる、というのは、Vimの活用シーンを広げる大きなきっかけになるはずだ。最初は「使いにくい意味不明なエディタ」という印象だった方も多いかもしれないVimだが、そのうちVimの強力さや便利さが伝わって利用頻度が上がっていく。そして今回のケースのようにCSVデータ専用のアプリケーションとしても利用できることがわかる。Vimに限らずプラグインを使うと、エディタというポジションから特定のデータを操作するための専用アプリケーションという側面まで出てくる。使えば使うほど便利になっていくエディタなのだ。
Linuxの管理においてエディタは切っても切り離すことができない。そして、エディタは管理のみならずLinuxを利用するユーザーという立場からしても欠かすことのできないアプリケーションだ。Vimの活用はそのままLinuxの活用に直結している。ぜひともここでVimスキルを引き上げていってもらえればと思う。
本連載で使っている~/.vimrcファイル
本連載で使っている設定ファイル(~/.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 列番号 | 指定した列内の最大値を出力 |
CSVMinCol | 現在の列内の最小値を出力 |
CSVMinCol 列番号 | 指定した列内の最小値を出力 |
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を指定するとヘッダとしてのハイライトが行われなくなる |