Quantcast
Channel: Vimタグが付けられた新着記事 - Qiita
Viewing all articles
Browse latest Browse all 5608

VimでCSVの列を並べ替える

$
0
0

具体例

country,name,sex,age
Japan,Ichiro,male,20
US,Jiro,female,10
Thailand,Saburo,male,0

name,age,sex,country
Ichiro,20,male,Japan
Jiro,10,female,US
Saburo,0,male,Thailand

にします

やり方

2つのコマンドを使います

VimでCSVを開いて、下のコマンドを入力しEnter

/\v^([^,]*),([^,]*),([^,]*),([^,]*)$

そうすると、下のように全ての行がハイライトされると思います

Screen Shot 2016-03-03 at 00.11.44.png

次に、下のコマンドを入力しEnter

:%s//\2,\4,\3,\1

Screen Shot 2016-03-03 at 00.12.33.png

並べ替えられました!

解説

1つ目のコマンド

/\v^([^,]*),([^,]*),([^,]*),([^,]*)$

これは文字列を検索するコマンドで、/から後ろが検索する文字列(正規表現)です

このコマンドで使われている正規表現の意味だけ簡単に表で示します

正規表現意味
^行の先頭
$行の末尾
[^,],以外の文字
[^,]*,以外の文字の並び
()文字列を記憶

最後の()の意味ですが、例えば今回は([^,]*)としてるので、,以外の文字の並びを記憶します
記憶した文字列は、1番目の()で囲まれた文字列は\1、2番目は\2とすることで利用できます

CSVの各行は、,以外の文字の並びが,で区切られているので、検索が全ての行にヒットしました

/の直後にある\vは正規表現をエスケープする手間をなくすためのものです
Vimの標準では()が文字列を記憶してくれないので、\vなしで同じことをするためには次のコマンドを実行しないといけません

/^\([^,]*\),\([^,]*\),\([^,]*\),\([^,]*\)$

()をいちいちエスケープしないといけないのでめんどくさいですね

2つ目のコマンド

:%s//\2,\4,\3,\1

これは置換をするためのコマンドで、例えば

:[range]s/foo/bar

とした場合は、rangeの中のfooという文字列をbarに置換します

今回の場合、range%で、これは全ての行を表しています

fooにあたるところは何もありませんが、ここを省略した時は直前の検索で利用したコマンドがそのまま入ります
今回の場合、下のコマンドを入力したのと同じです

:%s/\v^([^,]*),([^,]*),([^,]*),([^,]*)$/\2,\4,\3,\1

実は、最初から上のコマンド1つ実行しただけでも同じ結果になりますが、
2つに分けたのには理由があるので、後で説明します

次に、barの部分にあたる\2,\4,\3,\1\1\2はそれぞれ1つ目のコマンドの()で囲まれた文字列を指しています
例えば具体例の1行目はcountry,name,sex,ageなので\1country\2nameを指しているという具合です
全ての行に対してこの操作をしているので、無事CSVの列を並べ替えられたというわけです

コマンドを2つに分けた理由

今回は、1つ目のコマンドでは検索だけ、2つ目のコマンドで置換するというふうにしました
理由は最初に検索だけすることで、置換しようとしている範囲が意図したものになっているか確認できますし、ファイルの内容を間違って変更する心配もないからです

特に、複雑な正規表現を作る時は何回かテストするので、検索と置換の作業を分けることで、テストのたびにファイルを変更してしまうということも無くなります


Viewing all articles
Browse latest Browse all 5608

Trending Articles



<script src="https://jsc.adskeeper.com/r/s/rssing.com.1596347.js" async> </script>