Created
March 15, 2024 10:32
-
-
Save takuya-andou/b0f808f113a82f63e91ead5bfc023a21 to your computer and use it in GitHub Desktop.
カレントディレクトリ以下のすべてのファイルの内容を1つの大きなテキストファイルにまとめるためのものです。
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# 作者: t_andou | |
# | |
# このスクリプトは、カレントディレクトリ以下のすべてのファイルの内容を再帰的に読み込み、 | |
# 1つの大きなテキストファイルにまとめるためのものです。 | |
# | |
# 使い方: | |
# 1. このスクリプトをプロジェクトのルートディレクトリに配置します。 | |
# 2. コマンドラインから `python merge_all.py` を実行します。 | |
# (merge_all.py は実際のスクリプトファイル名に置き換えてください) | |
# 3. スクリプトが実行されると、カレントディレクトリ以下のすべてのファイルの内容が | |
# 1つまたは複数の output*.txt ファイルにまとめられます。 | |
# 各出力ファイルのサイズは最大10MBに制限されます。 | |
# | |
# 除外ルール: | |
# - 隠しファイルとディレクトリ (ドット . で始まるもの) は除外されます。 | |
# - .gitignore と .mergeignore に記載されているパターンにマッチするファイルとディレクトリは除外されます。 | |
# - このスクリプト自体も除外されます。 | |
# | |
# 出力形式: | |
# - 各ファイルの内容は、ファイルの相対パスと内容を示すマークダウン形式で出力されます。 | |
# - ファイルの相対パスは1行目に記載されます。 | |
# - ファイルの内容はコードブロック (```) 内に記載されます。 | |
# - ファイル間は2つの空行で区切られます。 | |
import os | |
import fnmatch | |
def get_file_contents(file_path): | |
with open(file_path, 'r', errors='ignore') as file: | |
return file.read() | |
def write_to_file(file_path, content): | |
with open(file_path, 'w') as file: | |
file.write(content) | |
def is_hidden(path): | |
return path.startswith('.') | |
def should_exclude(file_path, exclude_patterns): | |
for pattern in exclude_patterns: | |
if pattern.endswith('/'): | |
if fnmatch.fnmatch(file_path, pattern[:-1]) or file_path.startswith(pattern[:-1]): | |
return True | |
else: | |
if fnmatch.fnmatch(file_path, pattern): | |
return True | |
return False | |
def should_exclude_directory(dir_path, exclude_patterns): | |
for pattern in exclude_patterns: | |
if fnmatch.fnmatch(dir_path, pattern) or dir_path.startswith(pattern): | |
return True | |
return False | |
def main(): | |
output_file_prefix = 'output' | |
output_file_extension = '.txt' | |
max_file_size = 10 * 1024 * 1024 # 10MB | |
current_file_size = 0 | |
current_file_index = 1 | |
current_file_content = '' | |
script_file = os.path.basename(__file__) | |
exclude_patterns = [script_file] | |
for ignore_file in ['.gitignore', '.mergeignore']: | |
if os.path.exists(ignore_file): | |
with open(ignore_file, 'r') as file: | |
exclude_patterns.extend(file.read().splitlines()) | |
for root, dirs, files in os.walk('.'): | |
dirs[:] = [d for d in dirs if not is_hidden(d)] | |
# 除外ルールに基づいてディレクトリをスキップ | |
dirs[:] = [d for d in dirs if not should_exclude_directory(os.path.join(root, d), exclude_patterns)] | |
for file in files: | |
if is_hidden(file): | |
continue | |
file_path = os.path.join(root, file) | |
relative_path = os.path.relpath(file_path) | |
if should_exclude(relative_path, exclude_patterns): | |
continue | |
file_content = get_file_contents(file_path) | |
content_to_add = f'{relative_path}\n```\n{file_content}\n```\n\n' | |
content_size = len(content_to_add.encode('utf-8')) | |
if current_file_size + content_size > max_file_size: | |
output_file_name = f'{output_file_prefix}{current_file_index}{output_file_extension}' | |
write_to_file(output_file_name, current_file_content) | |
current_file_index += 1 | |
current_file_size = 0 | |
current_file_content = '' | |
current_file_content += content_to_add | |
current_file_size += content_size | |
if current_file_content: | |
output_file_name = f'{output_file_prefix}{current_file_index}{output_file_extension}' | |
write_to_file(output_file_name, current_file_content) | |
if __name__ == '__main__': | |
main() |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment