タイトルの通りです。何かしらの理由でファイルシステムを使わずにディレクトリの中を探索する必要がある場合に役立つときがあるスクリプトを紹介します。
実際のコードは次です。ディレクトリと拡張子を指定するとそのディレクトリ以下を再帰的に検索し、指定した拡張子のファイルを「ディレクトリ名.txt」に出力するスクリプトです。拡張子の指定でいいものが思いつかない時php tmp.php --show-extとして動かすと指定したディレクトリ以下の拡張子を集計してリストとして表示します。
<?php
// 対象のディレクトリ
$directory = __DIR__ . '/vendor';
// 集めるファイルの拡張子。null なら全部集める
$ext = ['php', 'json', 'md'];
// php tmp.php --show-ext のようにして使う。↑の拡張子を決める時の手掛かりとして使う
if(isset($argv[1]) && $argv[1] === '--show-ext') {
showExtList($directory);
}else{
writeFile($directory, $ext);
}
/**
* 与えられたディレクトリ以下に存在するファイルを集めて、1つのファイルに書き込む
* @param string $directory 探索するディレクトリ
* @param array|null $ext 集めるファイルの拡張子。nullの場合は全てのファイルを集める
* @return void
*/
function writeFile(string $directory, array|null $ext = null): void
{
// 結果を保存するファイルのベース名
$baseOutputFile = basename($directory);
$outputFile = $baseOutputFile . '.txt';
// 出力ファイルを開く
$oFile = fopen($outputFile, 'w');
// foreach で再帰的にフォルダの中身を探索できるように準備
$iterator = new RecursiveIteratorIterator(new RecursiveDirectoryIterator($directory));
foreach($iterator as $file) {
// 探索で見つかった要素がファイルであり、指定した拡張子であるかチェック。もしそうならば追記コピーする
if($file->isFile() && (!$ext || in_array($file->getExtension(), $ext))) {
// 相対パスを取得
$relativePath = substr($file->getPathname(), strlen($directory) + 1);
echo $relativePath . PHP_EOL;
// ファイルパスを書き込む
fwrite($oFile, "----------\n" . $relativePath . "\n----------\n");
// ファイルの中身を書き込む
$iFile = fopen($file->getPathname(), "r");
while (($line = fgets($iFile)) !== false) {
fwrite($oFile, $line);
}
fwrite($oFile, "\n");
fclose($iFile);
}
}
fclose($oFile);
}
/** 与えられたディレクトリ以下に存在するファイルの拡張子のリストを表示する */
function showExtList(string $directory): void
{
// ディレクトリを開く
$iterator = new RecursiveIteratorIterator(new RecursiveDirectoryIterator($directory));
$extList = [];
foreach($iterator as $file) {
if($file->isFile()) {
$extList[$file->getExtension()] ??= 0;
$extList[$file->getExtension()]++;
}
}
// 拡張子リストを表示
asort($extList);
echo json_encode($extList, JSON_PRETTY_PRINT | JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES);
}
これでファイルをいったんまとめるとベクトル検索に使ったりGPTsに読み込ませたりなどといったことがやりやすくなります。最近ですとGPTsに読み込ませるのは特に有効です。文字列検索では見つけられないような探し方ができたり、コードジャンプで追えないようなコードのつながりを見つけたり、ドキュメントから漏れてる機能を見つけたりなど様々なことをしてくれます。