「あるディレクトリ配下に存在する指定拡張子ファイルを全て取得し、結果の一覧をファイル出力したい」
ある日の仕事の一環でこんな事があったので、簡単なスクリプトを作る時によく使うPythonでちゃちゃっと作ってみました。
要件のおさらい
例えば、以下のようなディレクトリ構成が存在していたとします。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 |
base_dir ├── category1 │ ├── category1.css │ ├── category1.html │ ├── category1.js │ ├── page1 │ │ ├── page1.css │ │ ├── page1.html │ │ └── page1.js │ └── page2 │ ├── child_page1 │ │ ├── child_page1.css │ │ ├── child_page1.html │ │ └── child_page1.js │ ├── page2.css │ ├── page2.html │ └── page2.js ├── category2 │ ├── category2.css │ ├── category2.html │ ├── category2.js │ ├── page3 │ │ ├── child_page2 │ │ │ ├── child_page2.css │ │ │ ├── child_page2.html │ │ │ └── child_page2.js │ │ ├── page3.css │ │ ├── page3.html │ │ └── page3.js │ └── page4 │ ├── page4.css │ ├── page4.html │ └── page4.js ├── index.css ├── index.html └── index.js |
上の図のrootディレクトリであるbase_dirから見て、配下全ファイルの中から拡張子が.htmlのファイルだけを抜き出して結果出力用ファイルに一覧で出力させたい。
1 2 3 4 5 6 7 8 9 |
index.html category1.html page1.html page2.html child_page1.html category2.html page3.html child_page2.html page4.html |
こんな感じで出力させた内容をファイルに書き出すのが今回のやりたい事です。
要件を満たす処理を実行するスクリプト作成
以下の条件を満たせれば良いだけで複雑な処理は必要ないので実現方法は何でも良かったのですが、手軽にすぐ作れる利点から最近よくこんな感じの便利スクリプトを作る時に使用しているスクリプト言語のPythonを選択して作ってみました。
・指定ディレクトリ配下の全ファイルを再帰的に探索していき、各ファイルの拡張子が指定した拡張子と一致した場合のみ書き込みを行い最終結果を指定ファイルに出力できること
・今回はサンプルとして、rootディレクトリに base_dir を指定
・同様にサンプルとして、出力対象ファイルの拡張子を .htmlファイル に指定
・同様にサンプルとして、出力先ファイル名を result_list.txt に指定
ということで、上記の機能要件を満たす処理を作ってみました。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 |
# -*- coding: utf-8 -*- import os.path # 探索元のrootディレクトリパス SEARCH_TARGET_BASE_DIR_PATH = 'base_dir' # 探索結果の出力先ファイルパス OUTPUT_FILE_PATH = 'result_list.txt' # 出力対象ファイル拡張子 TARGET_EXTENSION = '.html' def find_all_files(base_dir): for root, dirs, files in os.walk(base_dir): yield root for file in files: yield os.path.join(root, file) def create_target_file_list(): with open(OUTPUT_FILE_PATH, 'w') as f: for search_result_file in find_all_files(SEARCH_TARGET_BASE_DIR_PATH): if search_result_file.endswith(TARGET_EXTENSION): file_name = os.path.basename(search_result_file) f.write(file_name + '\n') create_target_file_list() |
base_dirディレクトリ配下の.hmtlファイルが全てresult_list.txtファイルに出力できるようになりました。
おまけ: 対象ファイルのパスも加えた形でExcelに出力してみる
上記で定めた要件は満たす事ができましたが、今回は結果ファイルを使って色々調査を行い、調査結果を結果ファイルに追記していきたいという希望があったので、下記二つの機能要件を追加し、Pythonスクリプトにも機能を追加してみました。
・結果を出力するファイルのファイル形式を.xlsにする
・出力内容として、ファイル名だけでなく、対象ファイルのrootディレクトリ(base_dir)以下のファイルパスも出力させる
Pythonスクリプトの方も上記追加機能要件を満たせる形に修正していきます。
Excel出力用に、xlwtライブラリを用意
PythonでExcelを行う際によく使われるxlwtですが、デフォルトで用意されているライブラリではない為、使用可能な状態になっていない場合にはpipで落としてきて使えるようにします。
1 |
$ pip install xlwt |
pipコマンドが使えない場合は、以下で使えるようになるのでまずはこちらから行なってください。
1 2 |
$ curl -O https://bootstrap.pypa.io/get-pip.py $ sudo python get-pip.py |
Pythonスクリプトの修正
Excel出力ができるようになったところで、先程作成したPythonの処理に若干変更を加えて要件を満たせるようにします。
変更点は上の追加の機能要件でも挙げた二つの内容で、結果を出力するファイルのファイル形式を.xlsにすることと、出力内容として、ファイル名だけでなく、対象ファイルのrootディレクトリ(base_dir)以下のファイルパスも出力させるの二つです。
また、出力先がExcelファイルなのでシート名としてhtml_listというシート名を仮で設定しておきました。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 |
# -*- coding: utf-8 -*- import os.path import xlwt # 探索元のrootディレクトリパス SEARCH_TARGET_BASE_DIR_PATH = 'base_dir' # 出力対象ファイル拡張子 TARGET_EXTENSION = '.html' # 探索結果の出力先ファイルパス OUTPUT_FILE_PATH = 'result_list.xls' # 探索結果の出力先シート名(出力先がExcelの場合) OUTPUT_SHEET_NAME = 'html_list' def write_header_info(sheet, row_num): sheet.write(row_num, 0, "fileName") sheet.write(row_num, 1, "filePath") row_num += 1 return row_num def find_all_files(base_dir): for root, dirs, files in os.walk(base_dir): yield root for file in files: yield os.path.join(root, file) def create_target_file_list(): book = xlwt.Workbook() row_num = 0 sheet = book.add_sheet(OUTPUT_SHEET_NAME) row_num = write_header_info(sheet, row_num) # ヘッダ情報書き込み。ヘッダ不要の場合はこの行をコメントアウトする for search_result_file in find_all_files(SEARCH_TARGET_BASE_DIR_PATH): if search_result_file.endswith(TARGET_EXTENSION): file_name = os.path.basename(search_result_file) sheet.write(row_num, 0, file_name) # ファイル名 sheet.write(row_num, 1, search_result_file.replace(file_name, '')) # ファイル名を除いた形のファイルパス row_num += 1 book.save(OUTPUT_FILE_PATH) create_target_file_list() |
作った処理を実行してみると…
上記の感じのExcelファイルが出力されれば完成です。
便利スクリプトは色々自作して溜めておくと勉強にもなるし同じようなことを次にやりたくなった時に便利だしで一石二鳥ですね!
ということで、今回は終わりです。