Security_Analysis

진단 Tool 제작_3 (데이터 분할 및 데이터 프레임화 코드 변경) 본문

현업/[dev]_Python

진단 Tool 제작_3 (데이터 분할 및 데이터 프레임화 코드 변경)

Positivie 2024. 7. 9. 21:28
728x90
반응형

앞서 글에서 데이터 분할은 완료하였고, 데이터 프레임도 했었는데 한가지 의문이 생겼다.

진단 Tool 제작_1 (데이터 분할) (tistory.com)

 

데이터 분할을 한다는 것은 "Script 결과" 를 특정 항목별로 분리해서 U-01.txt 와 같이 분리하는 것이였다. 

그렇다면,  구조는 아래와 같다

 

" 원본 스크립트 파일 " 을 분할하여 "항목별 텍스트 파일" 결과를 가지고 "데이터 프레임화" 하는 것이다. 
원본 결과를 가지고도 데이터프레임화를 할 수 있는데 굳이 항목별로 텍스트 파일을 만들어야 하는 의문이 생겼다. 

특정 문구를 가지고 Parsing 하면서 나머지 데이터를 지우면..
항목별 텍스트 파일 결과가 왜 필요하지..??

그리하여, 나는 "원본 스크립트 결과 파일" 을 통해 데이터 프레임화 하기로 코드를 바꾸기로 했다. 

input_dir = 'C:/Users/Modeling/data'

input_files = [f for f in os.listdir(input_dir) if f.endswith('.txt')]

for input_file in input_files:
    file_path = os.path.join(input_dir, input_file)
    file_name = os.path.splitext(input_file)[0]
    _, hostname, ip, os_type, date = file_name.split('_', 4)

 

data 경로에 원본 스크립트 결과 파일에 대해서 먼저 input_files 리스트에 포함시켜서, 

반복문을 통해서 파일명에 존재하는 Hostname, ip, os_type, date 값을 뽑아냈다. 

 

hostname, ip, os_type, date 를 뽑아낸 것은 DB를 활용하여 항목별(SRV-01, SRV-02 등) 로 테이블을 만들고, 그 테이블 내 데이터들을 한대의 자산에서 긁어왔다는 것을 인식할 수 있도록 서로 매핑하기 위해서다. 

# Hostinfo DB 경로 설정
    hostinfo_db_path = os_dbs.get(os_type.lower())
    hostinfo_conn = sqlite3.connect(hostinfo_db_path)
    hostinfo_cursor = hostinfo_conn.cursor()

    # Hostinfo DB 초기 설정
    hostinfo_cursor.execute('''
    CREATE TABLE IF NOT EXISTS hostinfo (
        id INTEGER PRIMARY KEY AUTOINCREMENT,
        filename TEXT,
        hostname TEXT,
        ip TEXT,
        os TEXT,
        date TEXT
    )
    ''')
    hostinfo_conn.commit()
    hostinfo_conn.close()

 

sqlite를 사용하여 id, filename, hostname, ip, os, date 등을 Host 정보에 포함시켰다. 

여기서 id값은 위에서 말한것처럼 각 항목별(u-01, u-02) 테이블의 현황을 넣을 때 하나의 결과에서 파싱했다는 것을 인식하기 위한 INDEX 값이다. 

 

 분할된 파일을 읽다보니 EUCKR, UTF8, CP949 등 다양한 인코딩 에러가 발생했다.  이 모든 인코딩에 대해서 내가 경우의 수를 전부 반영해야 했으나, 검색해보니 chardet 라는 훌륭한 모듈이 있었다. 

 

Chardet : 범용 문자 인코딩 탐지기 (

chardet · PyPI)

 

파일을 읽을 때 인코딩 기법을 확인하여 변경해주는 모듈이라고 한다. 이 모듈을 사용하니까 내가 사용하는 어떤 인코딩 기법에 대해서도 모두 변환이 가능했다. 

with open(file_path, 'r', encoding=encoding) as file:
        lines = file.readlines()

    data = []
    current_srv_id = None
    current_content = []
    skip_content = False

    for line in lines:
        stripped_line = line.strip()

        if "Reference File Check" in stripped_line:
            break

        if not stripped_line:
            continue
        if stripped_line.startswith("##STATUS##):
            continue
        if stripped_line.startswith("##_START_##"):
            continue
        if stripped_line.startswith("##_END_##"):
            skip_content = True
            continue

 

"##STATUS##"  라는 값을 기준으로 하단에 정보가 출력되고 있어서 해당 내용을 제외하고 하단 내용을 출력하도록 조절했고, 

지난번과 코드가 달라진 것은 START, END 사이의 결과를 제외하고

보고서에 작성하기 위한 "1. ~~~~", "2.~~~~~" 와 같은 내용이 포함되도록 코드를 변경했다.

        if stripped_line.startswith("[SRV-"):
            if current_srv_id is not None and current_content:
                combined_text = "\n".join(current_content)
                if combined_text:
                    data.append((current_srv_id, combined_text))
                else:
                    data.append((current_srv_id, "No relevant content"))
            current_srv_id = stripped_line.split()[0][1:-1]
            current_content = []
            skip_content = False
        elif not skip_content:
            current_content.append(stripped_line)

U- 항목번호를 기준으로 Parsing 하고 skip_content로 하나의 항목이 끝난 시점과 다음 항목이 시작하는 시점을 

False 와 True 값을 계속 변경하면서 current_content에 데이터를 넣기 위해서였다. 

 

이렇게 까지 하고 나서 combined_text에 저장된 내용을 데이터 프레임에 값을 넣기 위해서 data.append 하였다

# 결과 파일 경로 설정
    output_file = os.path.join(preprocess_output_dir, f'{file_name}.xlsx')
    all_data.to_excel(output_file, index=False)

이렇게 분리와 데이터 프레임화도 완료가 되었다. 

 

150여개의 자산에 대해서 72개의 항목이 담겨있는 하나의 텍스트 파일을 읽는다면 지난번보다 파일의 개수는 줄어들지만, 용량은 크기 때문에 속도가 과연 얼마나 차이가 나는지는 확인을 해봐야겠다. 

 

이제 데이터 분리와 데이터 프레임도 끝났으니 다음에 해야할 것은 DB에 Label 이 없는 상태로 저장하는 것이다. 

현재 떨어지는 엑셀 결과파일에는 현황은 포함되어 있지만 결과가 포함되어 있지 않다.

이 부분은 모델링을 하기위한 단계예서는 사람이 수동으로 현황에 맞는 결과를 넣어서 모델을 학습시켜야 하기 때문에 

예측이라는 개념이 통하지 않는다. 

즉, 이 파일을 가지고 진단을 하고 진단 결과를 Label에 써서 이미 DB에 Label이 없는 상태로 저장된 내용을 업데이트 하여 Label 값까지 추가해야 한다. 

728x90
반응형