루비 네번째 시간, 오늘은 파일을 다뤄보고자 한다.

 

파일에서 문자열 검색

access_log라는 파일을 대상으로 삼아 테스트하려고 한다. 이 파일은 억세스 로그 파일인데, 이런 내용들이 포함되어 있다.

127.0.0.1 - - - [04/Mar/2017:21:56:17 +0900] "GET /index.html HTTP/1.1" 200 29

우선 이 파일에 "2017"이라는 패턴이 들어있는지 보자.

# cat scanAccessLog.rb
if File.readlines("access_log").grep(/2017/).size > 0
  puts "Find 2017!"
end

위와 같은 소스가 있다. 한 번 돌려보자.

# ruby scanAccessLog.rb
Find 2017!

있다.

이번에는 날짜까지 검색해보려고 한다. 오늘이 2017년 3월 4일이다. "04/Mar/2017" 이 패턴이 있는지 보도록 수정하자.

if File.readlines("access_log").grep(/04\/Mar\/2017/).size > 0
  puts "Find 2017-03-04!"
end

결과는 굳이 보여드리지 않겠다. 참고로 위에 04/Mar/2017을 검색하기 위해 04\/Mar\/2017라는 패턴을 사용한 것은, 즉 Escape Character가 포함된 이유는.. 다 아리라 믿는다.

자 또 이번에는 예전에 배운 것을 최대한 활용해보자. 아예 날짜를 입력받아본다.

# cat scanAccessLog.rb
datePattern = ARGV[0]
 
if File.readlines("access_log").grep(/#{datePattern}/).size > 0
  puts "Find #{datePattern}!"
end

소스는 위와 같고, 이제 실행한다.

# ruby scanAccessLog.rb 03/Mar/2017
Find 03/Mar/2017!
# ruby scanAccessLog.rb 04/Mar/2017
Find 04/Mar/2017!
# ruby scanAccessLog.rb 05/Mar/2017
#

 3월 3일, 3월 4일은 있다고 하는데 미래인 3월 5일은 역시 당근 없다고 나온다.

 

문자열 자르기

04/Mar/2017 라는 거추장스러운 Argument를 어찌해야 할까. 

그래서 궁극적으로 04032017 이라는 mmddyyyy 형태의 Argument를 넣으면 오늘 날짜를 찾을 수 있는 로직을 만들고자 한다.

datePattern = ARGV[0]
 
dd = datePattern[0,2]
mm = datePattern[2,2]
yy = datePattern[4,4]
 
puts "#{dd}"
puts "#{mm}"
puts "#{yy}"

 Argument를 일(dd), 월(mm), 년(yy)으로 자르도록 하였다. 실행해보자.

# ruby scanAccessLog.rb 04032017
04
03
2017

 잘 잘렸다.

 

case 조건문

이전에 if 조건문에 대해서는 알아본 적이 있다. 오늘은 case 조건문에 대해 알아보려고 한다.

뭘 할거냐 하면, access log 상에는 월이 03이 아닌 Mar로 되어 있기 때문에 이제 03 이라는 월에 해당하는 값을 Mar로 바꿀 것이다.

# cat scanAccessLog.rb
datePattern = ARGV[0]
 
dd = datePattern[0,2]
mm = datePattern[2,2]
yy = datePattern[4,4]
 
puts "#{dd}"
puts "#{mm}"
puts "#{yy}"
 
case mm
when "01"
  monthName = "Jan"
when "02"
  monthName = "Feb"
when "03"
  monthName = "Mar"
when "04"
  monthName = "Apr"
when "05"
  monthName = "May"
when "06"
  monthName = "Jun"
when "07"
  monthName = "Jul"
when "08"
  monthName = "Aug"
when "09"
  monthName = "Sep"
when "10"
  monthName = "Oct"
when "11"
  monthName = "Nov"
when "12"
  monthName = "Dec"
end
 
puts "#{monthName}"

 이제 실행 결과를 보자.

# ruby scanAccessLog.rb 04032017
04
03
2017
Mar

Mar를 얻어냈다.

 

함수 (메소드) 사용하기

위에서 case 문으로 월의 이름을 얻어내는 로직을 넣었는데 해당 로직을 함수화해보자. 함수는 def를 사용한다.

# cat scanAccessLog.rb
datePattern = ARGV[0]
 
dd = datePattern[0,2]
mm = datePattern[2,2]
yy = datePattern[4,4]
 
puts "#{dd}"
puts "#{mm}"
puts "#{yy}"
 
def _getMonthName(mon)
  case mon
  when "01"
    return "Jan"
  when "02"
    return "Feb"
  when "03"
    return "Mar"
  when "04"
    return "Apr"
  when "05"
    return "May"
  when "06"
    return "Jun"
  when "07"
    return "Jul"
  when "08"
    return "Aug"
  when "09"
    return "Sep"
  when "10"
    return "Oct"
  when "11"
    return "Nov"
  when "12"
    return "Dec"
  end
end
 
monthName = _getMonthName(mm)
 
puts "#{monthName}"

위와 같이 _getMonthName이라는 함수를 만들었다. 결과는? 

# ruby scanAccessLog.rb 04032017
04
03
2017
Mar

잘 됐다.

이제 거의 끝까지 왔다. mmddyyyy 패턴으로 검색이 가능해질까?

# cat scanAccessLog.rb
datePattern = ARGV[0]
 
dd = datePattern[0,2]
mm = datePattern[2,2]
yy = datePattern[4,4]
 
def _getMonthName(mon)
  case mon
  when "01"
    return "Jan"
  when "02"
    return "Feb"
  when "03"
    return "Mar"
  when "04"
    return "Apr"
  when "05"
    return "May"
  when "06"
    return "Jun"
  when "07"
    return "Jul"
  when "08"
    return "Aug"
  when "09"
    return "Sep"
  when "10"
    return "Oct"
  when "11"
    return "Nov"
  when "12"
    return "Dec"
  end
end
 
monthName = _getMonthName(mm)
 
finalDatePattern = "#{dd}/#{monthName}/#{yy}"
 
puts "input is #{finalDatePattern}"
 
if File.readlines("access_log").grep(/#{finalDatePattern}/).size > 0
  puts "Find #{datePattern}!"
end

결과를 보자.

# ruby scanAccessLog.rb 04032017
input is 04/Mar/2017
Find 04032017!

 

다음에 또 만나요.