오늘은 주어진 파일에서 문자열을 추출하고 다루는 일을 해볼 것입니다. 스텝별로 진행합니다.
시작!
1. 간단하게 샘플 텍스트가 저장된 test.txt 라는 파일을 읽는 작업입니다.
with open('test.txt') as f:
fileContent = f.readlines()
fileContent = [x.strip() for x in fileContent]
print(fileContent)
실행결과
$ python readFile.py ['This is a test text1.', 'This is a test text2.']
2. 1과 동일하나 test.txt 라는 파일을 인자로 입력받는 기능을 갖습니다. (지난번 MD5 hash 구하기 편에서도 이러한 부분이 포함되어 있습니다)
import sys
fileName = sys.argv[1]
with open(fileName) as f:
fileContent = f.readlines()
fileContent = [x.strip() for x in fileContent]
print(fileContent)
실행결과
$ python readFile.py test.txt ['This is a test text1.', 'This is a test text2.']
3. 1, 2는 결과가 쭉 나열되어 나옵니다. 이를 실제 test.txt 내 텍스트처럼 여러 줄로 보여주게 수정하겠습니다.
import sys
fileName = sys.argv[1]
with open(fileName) as f:
fileContent = f.readlines()
fileContent = [x.strip() for x in fileContent]
for line in fileContent:
print(line)
실행결과
$ python readFile.py test.txt This is a test text1. This is a test text2.
4. 이제 진짜 access.log 파일로 분석을 시작하려 합니다. 그리고 각 라인(결과)을 다시 blank를 기준으로 나눕니다.
import sys
fileName = sys.argv[1]
with open(fileName) as f:
fileContent = f.readlines()
fileContent = [x.strip() for x in fileContent]
for line in fileContent:
splitLine = line.split()
print(splitLine)
실행결과
$ python readFile.py access.log ['192.168.176.17', '-', '-', '[21/May/2012:07:45:53', '+0900]', '"GET', '/uploads/images/sch_box_g04.gif', 'HTTP/1.1"', '304', '0'] ['192.168.176.17', '-', '-', '[21/May/2012:07:45:52', '+0900]', '"GET', '/uploads/images/sch_box_g07.gif', 'HTTP/1.1"', '304', '0'] ['192.168.176.17', '-', '-', '[21/May/2012:07:45:54', '+0900]', '"POST', '/meeting.deleteReservateDo.jsp', 'HTTP/1.1"', '200', '650944']
5. 실제 요청은 7번째 자리에 있네요. 인덱스로는 6이겠지요. (0부터 시작이니까) print(splitLine) 를 print(splitLine[6]) 로 바꾸고 다시 실행합니다.
실행결과
/left_menu.jsp /images/end_logo.gif /images/main_img.gif /images/quick.gif
6. 너무 속도가 안나서.. 빨리 빨리 넘어가겠습니다. 이제 확장자만 잘라서 리스트에 담고 출력하는 것까지 작업합니다.
import os
import sys
fileName = sys.argv[1]
with open(fileName) as f:
fileContent = f.readlines()
extTable = {}
fileContent = [x.strip() for x in fileContent]
for line in fileContent:
splitLine = line.split()
ext = os.path.splitext(splitLine[6])[1]
if ext.startswith('.'):
ext = ext[1:]
if len(ext) > 0:
if ext in extTable:
extTable[ext] += 1
else:
extTable[ext] = 1
print(extTable)
실행결과
$ python readFile.py access.log
{'css': 81, 'gif': 199, 'dev': 266, 'jpg': 3, 'js': 60, 'htc': 178, 'jsp': 70, 'ico': 4, 'ajax': 16, 'htm': 5, 'dev?query=4492&meetingday=20120529&popupDiv=Y': 1}
7. 어쩌고.dev?query= 와 같이 쿼리스트링이 달려있는 요청에 쿼리스트링이 다 딸려왔네요? 수정합니다.
import os
import sys
fileName = sys.argv[1]
with open(fileName) as f:
fileContent = f.readlines()
extTable = {}
fileContent = [x.strip() for x in fileContent]
for line in fileContent:
splitLine = line.split()
ext = os.path.splitext(splitLine[6])[1]
if ext.startswith('.'):
ext = ext[1:]
if '?' in ext:
queryIndex = ext.find('?')
ext = ext[:queryIndex]
if len(ext) > 0:
if ext in extTable:
extTable[ext] += 1
else:
extTable[ext] = 1
print(extTable)
실행결과
$ python readFile.py access.log
{'css': 81, 'gif': 199, 'dev': 267, 'jpg': 3, 'js': 60, 'htc': 178, 'jsp': 70, 'ico': 4, 'ajax': 16, 'htm': 5}
8. 7번(혹은 6번)은 치명적인 단점이 있습니다. 뭘까요? 8번은 모두 생각하는 시간을 갖는 스텝입니다.
9. 7번(혹은 6번)은 확장자가 별도로 없는 요청, 예를 들어 / 같은 것은 카운트가 안됩니다. 패치합시다.
import os
import sys
fileName = sys.argv[1]
with open(fileName) as f:
fileContent = f.readlines()
extTable = {}
fileContent = [x.strip() for x in fileContent]
for line in fileContent:
splitLine = line.split()
ext = os.path.splitext(splitLine[6])[1]
if len(ext) > 0:
if ext.startswith('.'):
ext = ext[1:]
if '?' in ext:
queryIndex = ext.find('?')
ext = ext[:queryIndex]
if len(ext) > 0:
if ext in extTable:
extTable[ext] += 1
else:
extTable[ext] = 1
else:
if 'noExt' in extTable:
extTable['noExt'] += 1
else:
extTable['noExt'] = 1
print(extTable)
실행결과
$ python readFile.py access.log
{'css': 81, 'gif': 199, 'dev': 267, 'jpg': 3, 'js': 60, 'noExt': 117, 'htc': 178, 'jsp': 70, 'ico': 4, 'ajax': 16, 'htm': 5}