Skip to content

Instantly share code, notes, and snippets.

@gb-swatanabe
Last active October 20, 2015 05:32
Show Gist options
  • Save gb-swatanabe/6e58ed60fd075adca496 to your computer and use it in GitHub Desktop.
Save gb-swatanabe/6e58ed60fd075adca496 to your computer and use it in GitHub Desktop.
各行にIPアドレスが含まれているファイル(DNSのzoneファイル等)をそのIPアドレス順にRubyっぽくソートする
#!/usr/bin/env ruby
#encoding: utf-8
class Array
def ipsort
self.ipsort2
end
def ipsort1
# IPアドレスを含む行と含まない行にわけ、前者をソート
# 正規表現のマッチングが3回発生していてダサい
ipaddr = %r((\d{1,3})\.(\d{1,3})\.(\d{1,3})\.(\d{1,3}))
self.select{|line| ! line.match(ipaddr)} +
self.select{|line| line.match(ipaddr)}.sort_by{|line|
line.match(ipaddr)
"%03d%03d%03d%03d_%s" % [$1,$2,$3,$4,line]
}
end
def ipsort2
# IPアドレスを含む/含まないをEnumerable#partitionを使って分割
# 正規表現のマッチングは2回。少しマシだがもう少しなんとかならないか
ipaddr = %r((\d{1,3})\.(\d{1,3})\.(\d{1,3})\.(\d{1,3}))
with_ip, without_ip = self.partition{|line| line.match(ipaddr)}
without_ip +
with_ip.sort_by{|line|
line.match(ipaddr)
"%03d%03d%03d%03d_%s" % [$1,$2,$3,$4,line]
}
end
def ipsort3
# 1回の正規表現マッチングでソート条件までカバーする
# 結果eachループが2回だし長いし元データ壊してsliceで切り取ってるしなんかダサい
ipaddr = %r((\d{1,3})\.(\d{1,3})\.(\d{1,3})\.(\d{1,3}))
without_ip = Array.new
with_ip = Array.new
self.each{|line|
if line.match(ipaddr) then
with_ip << "%03d%03d%03d%03d_%s" % [$1,$2,$3,$4,line]
else
without_ip << line
end
}
without_ip +
with_ip.sort.each{|line| line.slice!(0,13)}
end
end
puts readlines.ipsort
@gb-swatanabe
Copy link
Author

注意:(ソート対象の)ファイルが大きいと死ぬ

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment