chrisbra/csv.vimでCSVファイルを編集

chrisbra/csv.vimプラグインはCSVデータを編集するための基本的な機能を提供している。「エディタを使い、手動でCSVデータを作成する」というのは、データが小さくレコード数が数十行~数百行程度であればよいが、それを超えてくると面倒だ。そういった場合にはプログラミング言語を使ってデータを加工したり、それこそスプレッドシートアプリケーションを使ったほうがよいのではないかと思う。しかし、chrisbra/csv.vimも基本となる編集機能は提供しており、操作の内容によってはchrisbra/csv.vimだけで十分ということもある。

chrisbra/csv.vimプラグインの機能のなかでも、特にCSVデータの編集に関係あるものをまとめると次のようになる。

コマンド 内容
CSVAddColumn 現在の列の右側に新しい列を追加
CSVAddColumn 列番号 指定した列の右側に新しい列を追加
CSVColumn 現在の列をコピー
列番号CSVColumn 指定した列をコピー
CSVDupColumn 現在の列を右側に複製
CSVDupColumn 列番号 指定した列を右側に複製
CSVDeleteColumn 現在の列を削除
CSVDeleteColumn 列番号 指定した列を削除
CSVMoveColumnor 現在の列を最後の列の右側へ移動
CSVMoveColumn 列番号 列番号 最初に指定した列を、2つ目に指定した列の右側へ移動
CSVNewRecord 新しい行を作成
CSVSubstitute 列番号/パターン/文字列/ 指定した列で置換
コマンド 内容
CSVSort 現在の列でファイルをソート
CSVSort 列番号 現在の列でファイルをソート
CSVSort! 現在の列でファイルを逆順にソート
CSVSort! 列番号 現在の列でファイルを逆順にソート

特に便利なのは、列ごとの複製/削除はないだろうか。以降では、それぞれの操作方法を紹介する。

列の追加

Vimは行単位での動作に関しては多種多様な機能が用意されている。chrisbra/csv.vimで提供される編集機能は、主に行ではなく列に対する操作だ。Vimは列単位での操作はあまり提供していない。テキストデータはその特性上、行単位での操作は共有で用意できても、列での共通の操作を提供するというのは難しいのだ。列方向の操作に関しては、データ形式ごとに個別に提供することになる。

chrisbra/csv.vimでは「CSVAddColumn」で新しく列を追加することができる。カーソルのある列の1つ右側に新しい空の列が追加されるといった動作になる。

「CSVAddColumn」で列を新しく追加

現在の列の右側に空の列が追加される

エディタでCSVデータを編集していると、どこが同じ列であるのかの判断が難しくなる。CSVAddColumnで空の列を追加してあげてから、そこに値を書き込んでいくような編集を行う。

列の複製

chrisbra/csv.vimでは「CSVColumn」で列ごとコピーすることができる。

「CSVColumn」で列をコピー

「P」で貼り付けると、「CSVColumn」でコピーした列が現在の列の右側に貼り付けられる。「CSVColumn」→「P」の流れで列を複製だと覚えてしまおう。

「P」で現在の列の右側に貼り付け

「CSVColumn」→「P」の操作は、「CSVDupColumn」を使うと一発でできる。

「CSVDupColumn」でコピーと貼り付けを一気に行うことができる

列が複製されている

前者の操作方法のほうが覚えやすく応用しやすいかもしれない。

列の削除

今回紹介する機能では、この「現在の列を削除する」機能が一番使われるかもしれない。CSVデータを扱っていると、特定の列だけ欲しいことがある。chrisbra/csv.vimでは「CSVDeleteColumn」で列を削除することができる。この機能を使えば、欲しい列だけ残してほかの列は削除するといったことができるわけだ。

「CSVDeleteColumn」で現在の列を削除

削除した後の様子

列を削除する場合、まずファイルをコピーしてどちらかのファイルを編集することになるだろう。そして欲しい列以外の列を全部削除する。これで欲しい列だけを取り出すという作業を完了することができる。

同じ操作をエディタの機能だけでやろうとすると、かなり複雑な正規表現を使うか、Vimの繰り返し処理機能を駆使して同じ処理をすることになる。chrisbra/csv.vimの機能を使えばそれが簡単に済むというわけだ。

列の移動

chrisbra/csv.vimでは「CSVMoveColumn」で列の移動を行うことができる。第1引数に対象となる列、第2引数に移動先を指定する。これにより、指定した列の右側へ列が移動する。

「CSVMoveColumn」で列を移動させることができる

第2引数で指定した列の右側へ移動する

列の移動をプラグインを使わないでやるとなると、これもかなり面倒な処理が必要になる。それがchrisbra/csv.vimを使えば、一発で完了するのだ。

行の追加

chrisbra/csv.vimは行方向(レコード)の編集機能はあまり提供していないのだが、「CSVNewRecord」は覚えておいてよいかもしれない。このコマンドは空のレコードを追加してくれる。

「CSVNewRecord」で空のレコード(行)を追加

空の状態で列が追加される

行を複製して編集しても同じことができるのでそれほど必要性は高くないが、空の状態で追加されるので新しくレコードが追加されたことがわかりやすいというのはあると思う。

あれこれと複雑な編集作業を行うのであればスプレッドシートアプリケーションを使ったほうが楽ではないかと思う。ただ、すでにやることが決まりきっており、chrisbra/csv.vimの提供している機能で足りるのであれば、chrisbra/csv.vimを使ったほうが手軽というケースもあると思う。結局必要と提供されている機能のマッチングでしかないのだが、VimでCSVファイルを編集するというを考えたこともなかったということであれば、これを機にchrisbra/csv.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を指定するとヘッダとしてのハイライトが行われなくなる