IPアドレスをソートする
sort コマンドでip addr をソートすると、文字列順になってしまう。
なのでIP アドレスを文字列でソートすると、めんどくさい
解決策
- sort コマンドのオプションつける(この記事)
- ip addr を int にする。別記事
- sort -V を使う。
まずは、sort コマンドのオプションで解決する方法を探る
IPアドレスをソートするなら、-V
オプションでバージョン番号としてソートするのが速い。
## 最速解決 sort -V
上記のような方法が不可能な環境もある、この記事私が想定しているのはbusyboxのsort や BSDのSortコマンドも含め考えたい。
ip アドレスのソートの問題。
たとえば、次を実行すると。
cat << EOS | sort 172.16.10.1 172.16.1.10 172.16.10.2 EOS
実行結果は正しい(ように錯覚する)
172.16.1.10 172.16.10.1 172.16.10.2
しかし、次を実行すれば
cat << EOS | sort 172.16.10.2 172.16.1.1 172.16.2.10 EOS
実行結果は「文字列」としてソートされてるとわかる。
172.16.1.1 172.16.10.2 172.16.2.10
sort オプションでの解決。
sort コマンドのオプションで解決させてみる。
sort -n -k 3 -t '.'
オプションについては、次のように指定してる。
# -t は区切りを指定 # -k はカラムを指定する最大2個 # -n は数字順に並べる。
実行例
cat << EOS | sort -n -k 3 -t '.' 172.16.1.1 172.16.2.10 172.16.10.2 EOS
実行結果
172.16.1.1 172.16.2.10 172.16.10.2
ただ、これだと、一つのオクテットしかソートされない。
そこで、複数のカラムに対して「数字順にソートする」
sort -t '.' -k 3,3n -k 3,4n
第1,2オクテットも対象にしたい。
そこで、-k
を重ねがけする。
ip アドレスのソート
sort -t '.' -n -k 1,2 -k 3,4
-k は2つまで
だけど、複数書ける。
なので、3,4 オクテットと1,2 オクテットを別々にオプションとして指定している。
実行例
cat <<EOS | sort -t '.' -n -k 1,2 -k 3,4 192.168.12.11 192.168.2.11 192.168.21.11 172.16.21.11 172.16.121.11 10.1.1.11 10.10.10.11 10.2.10.11 EOS
実行結果
10.1.1.11 10.10.10.11 10.2.10.11 172.16.21.11 172.16.121.11 192.168.2.11 192.168.12.11 192.168.21.11
ただ、これだと、1,2オクテットが文字列になってしまう。開始と終了で数字評価指定するのは困難だ。
そこで、重ねがけにオプション -k, --key=KEYDEF
をちゃんと指定する。
KEYDEF は F[.C][OPTS][,F[.C][OPTS]] の書式で、開始位置と停止位置を指定します。
F はフィールド番号で、 C はフィールド内の文字位置です。両方とも開始番号は 1 で す。 停止位置はデフォルトでは行末です。-t と -b の両方とも指定がない場合、 フィールド内の文字は、前にある空白の開始から数えられます。 OPTS には、1 文字の 並び替えオプション [bdfgiMhnRrV] を一つ以上指定します。 OPTS で指定されたキー の並び替えオプションは、グローバルな並び替えオプション より優先されます。キー が指定されない場合、行全体がキーとして使用されます。 正しくないキーの使用を突 き止めるには --debug を使ってください
( man sort より抜粋)
いい感じにやるには、-k
の重ねがけしかない。
cat <<EOS | sort -t '.' -k1,1n -k 2,2n -k 3,3n -k 4,4n 192.168.12.11 192.168.2.11 192.168.21.11 172.16.21.11
ドメイン名の場合
echo dns10.quad9.net dns.opendns.com doh.opendns.com dns11.quad9.net | xargs -n 1 | sort -t '.' -k2
などとすれば、ある程度はソートできる。 sort コマンドは最終カラム(末尾フィールド列)を指定する方法がないので、これ以上の詳細なソート(ドメイン名・パス)などはawk などほかのツールと組み合わせる必要がある。
ip v4アドレスはオクテットと表記が固定されているので、この記事のようなソートコマンドによるソートが可能です。
ip v6 アドレスは省略記法があるので、ドメイン名とおなじく、sort単体で並べるのは難しい。省略記法を使ってない、または、省略記法展開するという場合においてはv6アドレスもソートが可能。
まとめ
これで、IPアドレスを数字順にソートすることができる。
sort -t '.' -k1,1n -k 2,2n -k 3,3n -k 4,4n
オプションをつければgnu の基本的なコマンドだけで ip アドレスを扱えることがわかる。
v6の場合は、HEXなのでちょっとめんどくさい。また今度考えることにする。
関連資料
sort を区切り文字でカラム指定出そーつとする場合。 sortコマンドで列を指定、数順など指定する。 - それマグで!
参考資料
man sort