📁
インフラ運用の現場で役立つ!Pythonで2つのCSVから「変更点」を自動抽出する方法
1.はじめに
サーバー内のファイル調査や棚卸しで、定期的にファイル一覧をCSV化している方は多いと思います。
前回の記事では「ファイル一覧を再帰的に取得してCSVに出力するスクリプト」を作成しました。
しかし、運用を続けていると必ずこう思うはずです。
「1ヶ月前と比較して、結局どのファイルが増えて、どれが更新されたの?」
今回は、「新旧2つのCSV」を突き合わせ、差分レポートを自動生成するツールを作ります。
2.作成したコード
import pandas as pd
import sys
import os
def main():
#引数のチェック
if len(sys.argv) < 3:
print("Usage: python csv_diff.py [旧ファイルパス] [新ファイルパス]")
return
old_path = sys.argv[1]
new_path = sys.argv[2]
#CSVの読み込み
try:
df_old = pd.read_csv(old_path, encoding="utf-8-sig")
df_new = pd.read_csv(new_path, encoding="utf-8-sig")
except Exception as e:
print(f"Error: ファイルの読み込みに失敗しました。 {e}")
return
#比較のキーとなる列を指定
cols = ["第1階層", "第2階層", "第3階層(以降のパス含む)", "ファイル名"]
df_diff = pd.merge(df_old, df_new, on=cols, how='outer', indicator=True, suffixes=('_旧', '_新'))
#比較結果の判定
def judge_diff(row):
if row['_merge'] == 'right_only':
return '追加'
elif row['_merge'] == 'left_only':
return '削除'
elif row['_merge'] == 'both':
if row['サイズ(KB)_旧'] != row['サイズ(KB)_新']:
return '更新'
else:
return '変更なし'
return '不明'
#「比較結果」列を左端(インデックス0)に挿入
df_diff.insert(0, '比較結果', df_diff.apply(judge_diff, axis=1))
#不要な列の整理と出力
df_final = df_diff.drop(columns=['_merge'])
output_name = f"diff_report.csv"
df_final.to_csv(output_name, index=False, encoding="utf-8-sig")
print(f"比較完了!結果保存先: {output_name}")
if __name__ == "__main__":
main()
3.コードのポイント
「差分を見るならWinMergeで十分では?」と思うかもしれません。しかし、インフラ実務ではPython自作ツールには以下の大きなメリットがあります。
並び順に左右されない: WinMergeなどのテキスト比較は1行ズレると崩れますが、Pythonは「ファイル名」をキーに突合するので、データの順序が変わっても正確に判定できます。
4.実行結果

5.まとめ
これまで比較ツールの定番としてWinMergeを愛用してきました。視覚的にどこが違うか一目でわかる便利さは、何物にも代えがたいものです。
しかし、数千、数万行におよぶファイルリストを扱う現場では、「行ズレ」が問題になってしまいます。
1行データが増減するだけで、意図しない場所で差異を誤認し、本来見つけるべき変化を見逃したりするリスクがありました。行数が多いほど、この「ズレの目視確認」は運用ミスの温床となってしまいます。
もし同じようにWinMergeの「ズレの目視確認」に限界を感じている方がいれば、ぜひこのPythonスクリプトを使ってみてください。
Discussion