#やりたいこと
Cisco の show tech や Junos の RSI 等のログファイルから最初に確認する定番箇所だけ抜粋したい。
対象のログファイルは数万行あるが、構成は 'show xxxx' の羅列である。また冗長構成によっては同じコマンドが複数回実行される場合がある。
show xxx1
show xxx1 の出力
show xxx2
show xxx2 の出力
show xxx3
show xxx3 の出力
show xxx4
show xxx4 の出力
show xxx5
show xxx5 の出力
上記の様なファイルから
show xxx2
show xxx2 の出力
show xxx5
show xxx5 の出力
の様な出力を得たい。
##環境
Windows 10 Enterprise
python3.7.3
##最終成果物
# -*- coding: utf-8 -*-
import re
import os
import glob
import codecs
import shutil
files = glob.glob(r'.\log\*')
for name in files:
file_name = name
file = open(file_name)
lines = file.readlines()
k = '--------------------------------------'
lines_strip = [line.strip() for line in lines]
line_show_list = [i for i, line in enumerate(lines_strip) if 'show ' in line]
l_001_i = [i for i, line in enumerate(lines_strip) if 'show version detail' in line]
l_002_i = [i for i, line in enumerate(lines_strip) if 'show chassis alarms' in line]
l_003_i = [i for i, line in enumerate(lines_strip) if 'show system core-dumps' in line]
l_004_i = [i for i, line in enumerate(lines_strip) if 'show chassis environment' in line]
l_005_i = [i for i, line in enumerate(lines_strip) if 'show chassis hardware detail' in line]
basename1 = os.path.basename(file_name)
file_ext = os.path.splitext(basename1)
basename2 = file_ext[0]
result1 = '{}_result.txt'.format(basename2)
open(result1,'w')
for no1_c in range(len(l_001_i)):
no1_list = line_show_list.index(l_001_i[no1_c])
no1_list_e = no1_list + 1
print(k, file=codecs.open(result1, 'a', 'utf-8'))
print(*lines_strip[line_show_list[no1_list]:line_show_list[no1_list_e]], sep="\n", file=codecs.open(result1, 'a', 'utf-8'))
for no2_c in range(len(l_002_i)):
no2_list = line_show_list.index(l_002_i[no2_c])
no2_list_e = no2_list + 1
print(k, file=codecs.open(result1, 'a', 'utf-8'))
print(*lines_strip[line_show_list[no2_list]:line_show_list[no2_list_e]], sep="\n", file=codecs.open(result1, 'a', 'utf-8'))
for no3_c in range(len(l_003_i)):
no3_list = line_show_list.index(l_003_i[no3_c])
no3_list_e = no3_list + 1
print(k, file=codecs.open(result1, 'a', 'utf-8'))
print(*lines_strip[line_show_list[no3_list]:line_show_list[no3_list_e]], sep="\n", file=codecs.open(result1, 'a', 'utf-8'))
for no4_c in range(len(l_004_i)):
no4_list = line_show_list.index(l_004_i[no4_c])
no4_list_e = no4_list + 1
print(k, file=codecs.open(result1, 'a', 'utf-8'))
print(*lines_strip[line_show_list[no4_list]:line_show_list[no4_list_e]], sep="\n", file=codecs.open(result1, 'a', 'utf-8'))
for no5_c in range(len(l_005_i)):
no5_list = line_show_list.index(l_005_i[no5_c])
no5_list_e = no5_list + 1
print(k, file=codecs.open(result1, 'a', 'utf-8'))
print(*lines_strip[line_show_list[no5_list]:line_show_list[no5_list_e]], sep="\n", file=codecs.open(result1, 'a', 'utf-8'))
shutil.move(result1, "C:/Users/navasato/Desktop/")
file.close()
##説明
files = glob.glob(r'.\log\*') ### 1 ###
for name in files:
file_name = name
file = open(file_name)
lines = file.readlines() ### 2 ###
k = '--------------------------------------'
lines_strip = [line.strip() for line in lines] ### 3 ###
line_show_list = [i for i, line in enumerate(lines_strip) if 'show ' in line] ### 4 ###
l_001_i = [i for i, line in enumerate(lines_strip) if 'show version detail' in line] ### 5 ###
(snip)
l_005_i = [i for i, line in enumerate(lines_strip) if 'show chassis hardware detail' in line]
- logフォルダの配下のファイル名を取得。
- 1行毎に読み込みリストに確認。
- 要素の改行コードを削除。
- 'show 'が含まれる要素のインデックス番号をリストに格納。
- 取得したいコマンド(show xxx2)が含まれる要素のインデックス番号をリストに格納。同一コマンドが複数回実施される事があるため、forで繰り返し。
basename1 = os.path.basename(file_name)
file_ext = os.path.splitext(basename1)
basename2 = file_ext[0]
result1 = '{}_result.txt'.format(basename2) ### 1 ###
open(result1,'w')
- ログファイル名の後ろに_result.txtを付けた出力ファイル名を生成。2系では%sを使いましたが、3系ではformatの使用がおすすめとのこと。
for no1_c in range(len(l_001_i)): ### 1 ###
no1_list = line_show_list.index(l_001_i[no1_c]) ### 2 ###
no1_list_e = no1_list + 1 ### 3 ###
print(k, file=codecs.open(result1, 'a', 'utf-8'))
print(*lines_strip[line_show_list[no1_list]:line_show_list[no1_list_e]], sep="\n", file=codecs.open(result1, 'a', 'utf-8')) ### 4 ###
(snip)
shutil.move(result1, "C:/Users/z2085102/Desktop/") ### 5 ###
- 取得したいコマンドの実行回数だけ繰り返し処理を行う。
- 取得したいコマンドが何番目のshowコマンドか格納する。
- 取得したいコマンドの次のshowコマンドを確認する。
- 2から3までの間の要素を最初のリストから出力ファイルに書き出す。
- 出力ファイルをデスクトップに移動する。
##課題
- logフォルダに複数ファイルを配置すると動かない。(最初に選択されたファイルのみで実行される)
- そもそもログ取得に失敗したりしている場合、期待動作とならない。
まぁちょっと楽したいくらいで作成したので、このあたりは一旦運用でカバー。
##宿題
- python実行ディレクトリに一旦出力ファイルを生成しているが、元々はフルパス指定でデスクトップにファイルを生成しようと考えた。以下の様に固定出力ファイル名でなら実装できたが、formatを使ったファイル名が生成できなかった。
print(*lines_strip[line_show_list[no1_list]:line_show_list[no1_list_e]], sep="\n", file=codecs.open('C:/Users/navasato/Desktop/result.txt', 'a', 'utf-8'))
- 内包表記が使いこなせていない。