この記事は何
shellgei160を通じて言語習得 Advent Calendar 2023に参加しています。
書籍「シェル芸ワンライナー160本ノック」の例題をRubyで解いてみて、Rubyの学習に役立てようとするものです。
例題はこちらのリポジトリで公開されているものに限ります。
https://github.com/shellgei/shellgei160
実行環境など
- Docker image: ruby:3.0.2
- 上記リポジトリをクローンした上で、リポジトリのルートディレクトリ直下に
answer-ruby
ディレクトリを作り、その中に解答となるファイルを作成していきます。
今回のテーマ
$ awk -F: '{print $(NF-2)}' access.log | awk '$1<"12"{print "午前"} $1>="12"{print "午後"}' | sort | uniq -c
ログの中で時間のフィールドだけを抜き出し、その時間が午前か午後かを判別し、それぞれの個数をカウント・表示する。
解
logs = File.open('qdata/8/access.log', 'r').readlines
# am? receives a record including 02/Jun/2016:15:04:05 +0900 time format
def am?(record)
re = %r{\[\d{2}/[a-zA-Z]{3}/\d{4}:(\d{2}):}
h = record.match(re)[1].to_i
h < 12
end
n_am = logs.count { |log| am?(log) }
n_pm = logs.size - n_am
puts "午前: #{n_am}\n午後: #{n_pm}"
所感
- 正規表現にマッチした部分文字列を
match(パターン)[1]
で抜き出せるのね。 - 午前か午後かを別のarrayに納めて、array.count(午前 or 午後)にしてカウントしても良かったかも。