Vim関連情報

[Vim問題] ソートと重複排除を同時に実行する方法は?

この記事では、Vim / neovim でプラグインを使わずに「ソート(並べ替え)を行う」ためのコマンドについて、様々なバリエーションをご紹介します。

こちらは vim3 Advent Calendar 2019 10日目の記事です。

[解答] :sort u

Vim のソート機能のバリエーションは、けっこう豊富です。その中でも、直感的に使えそうなものをご紹介します。

Vimソート1. 重複排除しながら並べ替える

(ノーマルモード)
:sort u

これで全行ソートしながら、重複した行は排除してくれます。ソートは行頭文字から昇順です。逆順にするなら次のように ! を付与します。

(ノーマルモード)
:sort! u

これらを実行すると、次のようになります。

:sort u / :sort! u 実行例
:sort u / :sort! u 実行例

Vimソート2. 昇順または降順に並べ替える

(ノーマルモード)
:sort

これで全行にたいして、行頭からの文字列で昇順でソートします。降順にするのはこちら。

(ノーマルモード)
:sort!
:sort / :sort! 実行例
:sort / :sort! 実行例

Vimソート3. 範囲を指定して並べ替える

ファイル(バッファ)全体ではなく範囲を指定して実行することもできます。これはビジュアルモードとの組み合わせになります。

(ビジュアルモードで対象とする行を選択してから)
:sort  (昇順)
:sort! (降順)

これは Vimソート1 で紹介した重複排除でも同じです。

(ビジュアルモードで対象とする行を選択してから)
:sort u  (昇順)
:sort! u (降順)
範囲指定した :sort / :sort! 実行例
範囲指定した :sort / :sort! 実行例

Vimソート4. 番号順に並べ替える

番号順に並べ替えることも可能です。

(ノーマルモード または ビジュアルモードで範囲指定してから)
:sort n  (昇順)
:sort! n (降順)

通常の昇順と同じ結果になりそうなものですが、2桁の数字をキチンと判断できるのが違いとなります。次の動画を見ると明らかです。

:sort と :sort n / :sort! n の違いが分かる実行例
:sort と :sort n / :sort! n の違いが分かる実行例

ちなみに、この :sort n / :sort! n は各行の最初の数値(を示す文字列)を並べ替えの対象とします。次の動画を見ると明らかです。

:sort n / :sort! n が対象にする数値の例
:sort n / :sort! n が対象にする数値の例

Vimソート5. CSVファイルを並べ替える

かなり複雑な正規表現を組めば、CSVファイルのカラムを指定して並べ替えることもできます。

簡単な例がヘルプに掲載されています。

例えば、コンマで区切られた2番目のフィールドでソートするには:
    :sort /[^,]*,/

change – Vim日本語ドキュメント

これを別のカラムで使おうとすると、あまりにも複雑過ぎて自力でパターンを作るには至れず、こちらの記事を参考にさせてもらいました。

VimでCSVファイルの3列目をキーにしてソートする - Qiita
Vimには`:sort`コマンドが用意されています。これを使えば、バッファ内の行を柔軟にソートすることができます。 # `:sort`の基本 以下のようなファイルに対して、`:%sort` とすればファイル全体が辞書順でソートされま...

この記事を参考に、6列目を元に並べ替えるには次のコマンドを実行します。

:sort /\([^,]*,\)\{2\}\zs[^,]*/ r
CSVデータ「男女別人口-全国,都道府県(大正9年~平成27年)」を6列目で並べ替える例
CSVデータ「男女別人口-全国,都道府県(大正9年~平成27年)」を6列目で並べ替える例

ここまでして、CSVデータを Vim で並べ替える機会があるかというと悩ましいところです。第2、第3 の並べ替え優先度を指定することもできませんし…

Vimソート6. 該当する箇所で並べ替える

正規表現のパターンに該当する箇所を基準にして、並べ替えを行います。

:sort /{正規表現パターン}/ r

例えば、電話番号の真ん中の数字の文字列で並べ替える場合は、次のように実行します。

:sort! /-\d\d\d\d-/ r
あるいは
:sort! /-\d{4}-/ r
正規表現に該当する箇所を並べ替える例
正規表現に該当する箇所を並べ替える例

Vimソート7. 小数点数 / 2進数 / 8進数 / 16進数 で並べ替える

Vim 標準で、様々な種類の数値として捉えた並べ替えることができます。

並べ替え対象昇順降順
小数点数(Float):sort f:sort! f
2進数 (Binary):sort b:sort! b
8進数 (Octal):sort o:sort! o
16進数 (heXadecimal):sort x:sort! x

例えば、次のように先頭に数値を表す文字列がある場合の並べ替えです。

sort f で小数点数を並べ替える
sort f で小数点数を並べ替える

ヘルプ曰く、”行の({pattern}のマッチの後ろまたは内側の) 最初のテキスト”が対象となります。つまり、何もしていなければ行頭、ビジュアルモードなら選択した先頭のテキストとなります。

使う機会がある方が稀じゃないのかな?と思いますが、機能としてはキチンと搭載されています。

補足

使う場面が少なそうに感じますが、けっこうあります。

プログラミングの際、変数定義を昇順に並べ替えたり、Python の import文の並べ替えなど、個人的には範囲指定して並べ替えたいケースなど様々。

1〜2行なら必要ないですが、5行以上になると劇的に作業速度が変わります。

正規表現が絡むとかなり難しくなってしまいますが、ぜひ覚えて編集速度をアップさせましょう。

このVimコマンドの補足情報

  • 利用頻度2.0
  • 便利さ4.0
  • 覚え易さ3.0

関連するVimヘルプ

Vim のヘルプでは下記のように解説されています。

7. テキストのソート                                     sorting

Vimはソート関数とソートコマンドを備えている。ソート関数については sort()
uniq() を参照。

:sor :sort
:[range]sor[t][!] [b][f][i][n][o][r][u][x] [/{pattern}/]
                        [range]の行をソートする。範囲が指定されない場合は全行
                        をソートする。

                        [!]をつけると順序が逆になる。

                        [i]をつけると大文字・小文字を区別しない。

                        [n][f][x][o][b] オプションはどれかひとつのみ指定できる。

                        [n]をつけると行の({pattern}のマッチの後ろまたは内側
                        の)最初の10進数の数字でソートする。
                        数字が ‘-‘ で始まる場合、マイナスとみなされる。

                        [f] をつけると行の小数点数でソートする。
                        小数点数の値は ({pattern} によるマッチの後ろまたは内側
                        の) テキストを str2float() に渡すようにして決定される。
                        このオプションは Vim が小数点数サポートを有効にしてコ
                        ンパイルされたときのみ使える。

                        [x]をつけると行の({pattern}のマッチの後ろまたは内側の)
                        最初の16進数の数字でソートする。”0x” と “0X” は無視さ
                        れる。
                        数字が ‘-‘ で始まる場合、マイナスとみなされる。

                        [o]をつけると行の({pattern}のマッチの後ろまたは内側の)
                        最初の8進数の数字でソートする。

                        [b] をつけると({pattern}によるマッチの後ろまたは内側の)
                        行の最初の2進数でソートする。

                        [u]をつけると (u は unique=「一意の」という意味に基づ
                        く) 連続する同一行の最初の行だけを残す。([i]がつくと大
                        文字・小文字を無視する) このフラグがつかない場合、連続
                        する同一行はそのままの順序で残される。
                        Note: 先頭と末尾の空白が原因で異なる行にみなされるかも
                        しれない。

                        /pattern/が指定され、フラグ[r]がない場合は{pattern}に
                        マッチするテキストはスキップされる。これによって、その
                        マッチの後に来るテキストでソートできる。
                        スラッシュの代わりにどんなnon-letterでも使うことができ
                        る。
                        例えば、コンマで区切られた2番目のフィールドでソートす
                        るには:
                                :sort /[^,]*,/                        画面上の10桁目でソートするには(そのためタブとスペース
                        は同一視される):
                                :sort /.*\%10v/                        行中の最初の数字でソートするには:
                                :sort /.\{-}\ze\d/                        (解説: “.\{-}” は任意のテキストにマッチする。”\ze”
                        はそのマッチの終わりをセットし、”\d” は数字にマッチ
                        する。)
                        [r]がつくと、前述のように{pattern}をスキップするのでな
                        く、{pattern}にマッチする部分でソートする。
                        例えば、各行の最初の3文字だけでソートするには:
                                :sort /\a\a\a/ r
                        {pattern}が使われると{pattern}を含まない行は現在の順序
                        のままになる。逆順でソートすると、それらはソートされた
                        行の後で逆順になる。逆順でなければ、ソートされた行の前
                        でもとの順序のまま置かれる。

                        {pattern} が空である場合(例: // が指定されたとき)、
                        最後に使われた検索パターンが使われる。よって、まず検
                        索コマンドでパターンを確かめてみることができる。

Note: :global といっしょに :sort を使ってもマッチする行をソートすることに
はならない。これはまったく無意味である。

ソートの詳細は使っているライブラリ関数による。ソートが現在のロケールに従うとい
う保証はない。それを調べるには実行してみるしかない。ソートは「安定」ソートであ
る。

ソートは中断することができる。しかし中断するのが遅いと行が重複してしまうかもし
れない。これも使っているシステムのライブラリ関数による。

 vim:tw=78:ts=8:noet:ft=help:norl:

change – Vim日本語ドキュメント

こちらは、Vim上では下記のコマンドでヘルプを確認できます。

:help sorting
:help sort
:help sor

ヘルプで検索するときは、通常は大文字小文字は識別されませんので、どちらでも構いません。

参考書籍

こちらの書籍が参考になります。


Vim/neovim関連の書籍で、もっとも評判が良くてバイブルと呼んでる人もいる一冊です。Vim/neovimのバージョンに依存しない沢山のTips形式で、その表題通りに「思考のスピードで編集」できるようになるノウハウが詰まっています。その高い評価は Amazon のレビューからも分かる通りです。Vimmer なら必ず一度は読んでおいて間違いありません。


こちらもVim関連の書籍で評価が高い書籍の一冊です。vim-jpで見かける上級Vimmer(Vimサポーターズ)の皆様による、Vimを実践で使ったノウハウからプラグイン関連の情報が詰まっています。日本の Vim界隈を知る上でも是非一読しておきたい一冊です。

Vim/neovim の設定ファイルやプラグインなど、Vim script に関するノウハウがいくつも詰まった一冊です。日本で Vim Script をここまで深く解説している唯一の書籍と言えます。Vim力を伸ばしたいと考えるなら、絶対に避けては通れない書籍でしょう。

プロフィール
管理人
Vim太郎

Vim力アップして、そろそろ上級 Vimmer の仲間入りしたいIT系エンジニアの端くれです。読んでくる訪問者の皆様と一緒に、Vim力を上げていくことができる記事が書ければと考えています。

\フォローする/
\ シェアする /
\フォローする/
関連記事
Vim入門
タイトルとURLをコピーしました