@qii-sin (qii sin)

Are you sure you want to delete the question?

Leaving a resolved question undeleted may help others!

pythonでログをCSV化するには

Q&A

Closed

機器のログを取得し、CSV化しようとしましたが、ログが100万行程度あり、VBAでは全件表示できず、処理できない状態です。
そこで、pythonでログをCSV化しようとしておりますが、以下2点をどの様にすればよいのか全く分からない状況です。

<分からないこと>
①dataコマンドで表示した日時をID、MAC Addressなどの列の左側に追記したい
②ID、MAC Addressなどのヘッダーがコマンドを実行する度に表示されるので、CSV化する場合は、一番最初だけにしたい
③CSV化するにあたり、date、wlc# show ap-discovered、 Discovered APs and Stations(4249 entries)など不要な
 コマンド等は削除したい

<記載したコード>
sample.py

file_name = "C:/Work/before.log"

with open(file_name, 'r', encoding='shift-jis') as f:
    lines = f.readlines()

for line in lines:
    newlines = line.split()
    print(newlines)

<その他>
before.log→機器から出力したログ(100万行程度ですが、数行だけ掲載しております)
after.csv→before.logを加工し、実現したい形式

before.log

date
Tue Nov 11 00:00:00 JST 2022
wlc# show ap-discovered

ID     MAC Address       Type          Channel Confirmed-Channel SSID                             BSSID             Last            Previous  Current   Pkts Rx  RF Band       Name            

40     aa:bb:cc:dd:ee:ff AP            6       6                 samplesamplesample               11:22:33:44:55:66 00d:00h:00m:00s 0         -77       313382   802.11gn      AP1        
40     gg:hh:ii:jj:kk:ll AP            6       7                 samplesamplesample               22:33:44:55:66:77 00d:00h:00m:01s 0         -75       2840     802.11gn      AP2
	Discovered APs and Stations(4249 entries)
date
Tue Nov 11 00:05:00 JST 2022
wlc# show ap-discovered

ID     MAC Address       Type          Channel Confirmed-Channel SSID                             BSSID             Last            Previous  Current   Pkts Rx  RF Band       Name            

40     aa:bb:cc:dd:ee:ff AP            6       6                 samplesamplesample               11:22:33:44:55:66 00d:00h:00m:00s 0         -77       313382   802.11gn      AP1        
40     gg:hh:ii:jj:kk:ll AP            6       7                 samplesamplesample               22:33:44:55:66:77 00d:00h:00m:01s 0         -75       2840     802.11gn      AP2
date
Tue Nov 11 00:10:00 JST 2022
wlc# show ap-discovered

ID     MAC Address       Type          Channel Confirmed-Channel SSID                             BSSID             Last            Previous  Current   Pkts Rx  RF Band       Name            

40     aa:bb:cc:dd:ee:ff AP            6       6                 samplesamplesample               11:22:33:44:55:66 00d:00h:00m:00s 0         -77       313382   802.11gn      AP1        
40     gg:hh:ii:jj:kk:ll AP            6       7                 samplesamplesample               22:33:44:55:66:77 00d:00h:00m:01s 0         -75       2840     802.11gn      AP2
	Discovered APs and Stations(4249 entries)

after.csv

Day,Month,Date,Time,ID,MAC Address,Type,Channel,Confirmed-Channel,SSID,BSSID,Last,Previous,Current,Pkts,Rx,RF,Band,Name            
Tue,Nov,11,00:00:00,40,aa:bb:cc:dd:ee:ff,AP,6,6,samplesamplesample,11:22:33:44:55:66,00d:00h:00m:00s,0,-77,313382,802.11gn,AP1
Tue,Nov,11,00:00:00,40,gg:hh:ii:jj:kk:ll,AP,6,6,samplesamplesample,22:33:44:55:66:77,00d:00h:00m:00s,0,-77,313382,802.11gn,AP2        
Tue,Nov,11,00:05:00,40,aa:bb:cc:dd:ee:ff,AP,6,6,samplesamplesample,11:22:33:44:55:66,00d:00h:00m:00s,0,-77,313382,802.11gn,AP1
Tue,Nov,11,00:05:00,40,gg:hh:ii:jj:kk:ll,AP,6,6,samplesamplesample,22:33:44:55:66:77,00d:00h:00m:00s,0,-77,313382,802.11gn,AP2          

コード例をご提示いただき、ご教示いただけると助かります。

1 likes

2Answer

 Wikipediaでは船首から丸太(log)を投げて船尾までの時間を航海日誌に記録したことが、ログの由来とされています。
 私の記憶では、船尾からロープに繋いだ丸太(log)を投げ、ロープがピンとなった時間を記録したことになっています。

with open(file_name, 'r', encoding='shift-jis') as f:
    lines = f.readlines()
    for line in lines:
        ・・・・

f.read
f.readline
f.readlines と色々な読み込み方法があり

f.readline だと1行1行読めます。
VBAもメソッドの選択が誤ったと思われます。

さて、
そもそも、機器がログRFC 3164に準拠したものを出力するものを選択すべきでした。
1件1葉をもじって1件1行でログを出力することはトランザクションを管理する上で重要なことです。
too late と嘆いても詮無きことですので
現状のログ形式で話を進めます。

wlc# コマンド
   コマンドの結果の表示
   ・・・・
wlc#

1件1葉を特定し、コマンドの結果の表示をキーブレーク処理で編集することをお勧めします。

キーブレーク処理以外では awkでRS="¥r¥nwlc# "のように1行の概念を ¥r¥nwlc# ~ ¥r¥nwlc#  にして処理する考え方もあります。

暇人x in居酒屋

0Like

readlines はファイルの内容全体を一気に読み出します.
これは巨大なファイルを扱いきれない場合があります.

ファイル全体ではなく行単位で読み出して処理していくのをおすすめします.
例えば次のような流れになります:

DAYS_OF_WEEK = {'Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat', 'Sun'}

print("Day,Month,Date,...")  # ヘッダー行

with open('C:\\Work\\before.log', encoding = 'shift_jis') as f:
    for line in f:  # 1 行ずつ取得
        if line[0:3] in DAYS_OF_WEEK:  # 行の先頭が曜日名のとき
            prefix = ','.join(line.split()[:-2])  # 日付時刻を覚えておく
            continue

        if line[0].isdecimal():  # 行の先頭が数字のとき
            print(prefix + ',' + ','.join(line.split()))  # 日付時刻を先頭につけて出力
            continue

        # その他の行に対しては何もしない

ここでは行内容の場合分けや変換を雑に実装しましたが,
もっと丁寧にやるならば正規表現を使います.

0Like

Your answer might help someone💌