検索条件
全1件
(1/1ページ)
1.2.3.4ソートしたい対象が、シンプルに IP アドレスだけなら簡単。 bash ならね。
1.1.1.1
20.10.5.3
3.5.7.9
7.10.5.4
60.70.80.90
9.8.7.6
150.150.150.150
7.6.5.4
$ sort --version-sort sample.txt 1.1.1.1 1.2.3.4 3.5.7.9 7.6.5.4 7.10.5.4 9.8.7.6 20.10.5.3 60.70.80.90 150.150.150.150こちらは、まったく同じオプション(省略形)です。
$ sort -V sample.txt 1.1.1.1 1.2.3.4 3.5.7.9 7.6.5.4 7.10.5.4 9.8.7.6 20.10.5.3 60.70.80.90 150.150.150.150bash バージョンがちょっと古いなら、こんなオプションでも可能みたい。
$ sort -n -t '.' -k1,1 -k2,2 -k3,3 -k4n,4 sample.txt 1.1.1.1 1.2.3.4 3.5.7.9 7.6.5.4 7.10.5.4 9.8.7.6 20.10.5.3 60.70.80.90 150.150.150.150
example.jp,1.2.3.4こんなドメイン+IPアドレスになったりすると、上記のソートは使えませんね。
example.com,1.1.1.1
example.co.jp,20.10.5.3
work.example.jp,3.5.7.9
auction.example.com,7.10.5.4
www.example.jp,60.70.80.90
ftp.example.jp,9.8.7.6
mail.example.jp,150.150.150.150
auction.example.jp,7.6.5.4
$ sort --version-sort sample2.txt auction.example.com,7.10.5.4 auction.example.jp,7.6.5.4 example.com,1.1.1.1 example.co.jp,20.10.5.3 example.jp,1.2.3.4 ftp.example.jp,9.8.7.6 mail.example.jp,150.150.150.150 work.example.jp,3.5.7.9 www.example.jp,60.70.80.90IPアドレスでソートしたいのに、IPアドレスではなくドメインでのソートになっています。
$ unset list $ for i in $(cat sample2.txt) do tmp=$(echo $i | cut -d ',' -f 2) tmp2=$(php -r 'echo sprintf ("%u", ip2long("$argv[1]"));' $tmp) list=$(printf '%s\n%s,%u' "$list" $i $tmp2) done $ echo "$list" | sort -t ',' -n -k3 | grep -v "^$" example.com,1.1.1.1,16843009 example.jp,1.2.3.4,16909060 work.example.jp,3.5.7.9,50661129 auction.example.jp,7.6.5.4,117835012 auction.example.com,7.10.5.4,118097156 ftp.example.jp,9.8.7.6,151521030 example.co.jp,20.10.5.3,336200963 www.example.jp,60.70.80.90,1011241050 mail.example.jp,150.150.150.150,2526451350ここでは PHP のワンライナーを使ってますが、php コマンドが使えない場合はオクテット毎に桁の重みを計算しないとダメでしょうね。
$ awk -F '.' '{a=0;b=0;c=0;d=0;for(i=1;i<=NF;i++){a=$1*256*256*256;b=$2*256*256;c=$3*256;d=$4}; printf "%u\n", a+b+c+d}' sample.txt 16909060 16843009 336200963 50661129 118097156 1011241050 151521030 2147483647 117835012 $ # もしくは $ awk -F '.' '{a=0;b=0;c=0;d=0;for(i=1;i<=NF;i++){a=$1*256^3;b=$2*256^2;c=$3*256;d=$4}; printf "%u\n", a+b+c+d}' sample.txt 16909060 16843009 336200963 50661129 118097156 1011241050 151521030 2147483647 117835012 $ # もう少し短くできそう $ awk -F '.' '{a=0;for(i=1;i<=NF;i++){a=$1*256^3+$2*256^2+$3*256+$4}; printf " %u\n", a}' sample.txt 16909060 16843009 336200963 50661129 118097156 1011241050 151521030 2147483647 117835012できたので組み込んでみます。
$ unset list $ for i in $(cat sample2.txt) do tmp=$(echo $i | cut -d ',' -f 2) tmp2=$(echo $tmp | awk -F'.' '{a=$1*256^3+$2*256^2+$3*256+$4}{printf "%u", a}') list=$(printf '%s\n%s,%u' "$list" $i $tmp2) done $ echo "$list" | sort -t ',' -n -k3 | grep -v "^$" example.com,1.1.1.1,16843009 example.jp,1.2.3.4,16909060 work.example.jp,3.5.7.9,50661129 auction.example.jp,7.6.5.4,117835012 auction.example.com,7.10.5.4,118097156 ftp.example.jp,9.8.7.6,151521030 example.co.jp,20.10.5.3,336200963 www.example.jp,60.70.80.90,1011241050 mail.example.jp,150.150.150.150,2147483647……なんとなく、awk だけでも IP アドレスでソートできそうな予感をひしひしと感じてたりしますが、ここでは考えません。
$ echo "$list" | sort -t ',' -n -k3 | grep -v "^$" | cut -d "," -f 1,2 example.com,1.1.1.1 example.jp,1.2.3.4 work.example.jp,3.5.7.9 auction.example.jp,7.6.5.4 auction.example.com,7.10.5.4 ftp.example.jp,9.8.7.6 example.co.jp,20.10.5.3 www.example.jp,60.70.80.90 mail.example.jp,150.150.150.150
=LEFT(A1,SEARCH(".",A1,1)-1)*(256*256*256)+MID(A1,SEARCH(".",A1,1)+1,SEARCH(".",A1,SEARCH(".",A1,1)+1)-SEARCH(".",A1,1)-1)*(256*256)+MID(A1,SEARCH(".",A1,SEARCH(".",A1,1)+1)+1,SEARCH(".",A1,SEARCH(".",A1,SEARCH(".",A1,1)+1)+1)-SEARCH(".",A1,SEARCH(".",A1,1)+1)-1)*256+MID(A1,SEARCH(".",A1,SEARCH(".",A1,SEARCH(".",A1,1)+1)+1)+1,SEARCH(".",A1,SEARCH(".",A1,SEARCH(".",A1,1)+1)+1)-SEARCH(".",A1,SEARCH(".",A1,1)+1)-1)この関数、やっていることは . の位置を調べて mid で数値を抜き出し、各オクテットの重みを掛けてロングIPアドレスを算出しています。