ファイル削除手法の動作原理とメモリ使用量の違い
この記事では、ディレクトリ内の *.jpg ファイルを削除する際に使える3つの方法について、動作原理やメモリの使い方、各手法のメリットとデメリットを解説しています。
🔹 方法1: find + grep(最速で実行)
動作原理
-
find
コマンドでディレクトリ内の*.jpg
ファイルをすべてリストアップ- OS のファイルシステムを直接走査し、ファイル一覧を取得。
-
seq
で保持すべきファイル名のリストを作成。 -
grep -v -E
で削除対象のファイルを絞り込む。 -
xargs rm
で一括削除。
メモリの使い方
-
find:
カーネルのメモリ管理(ページキャッシュ)を利用してディレクトリのファイルリストを取得するため、メモリ消費は最小限。 -
seq | awk | sed:
連続する番号を生成し、正規表現でファイル名を作るための小規模なテキスト処理。 -
grep -E:
出力をストリーム処理するため、ファイルリスト全体をメモリに保持しない。 -
xargs rm:
rm コマンドをまとめて実行し、シェルのプロセス生成回数を抑制。
メリット
- ✅ ファイル一覧をストリーム処理するため、メモリ効率が良い。
- ✅ 削除対象を一括処理できるので、高速に動作。
- ✅ 大規模なファイル群(数万以上)でも比較的メモリを消費しない。
デメリット
- ❌ grep の正規表現が長すぎるとエラーが出る可能性がある。
- ❌ xargs の処理で大量の引数を渡すとエラーが発生する場合がある(対策:
xargs -n 100
などで分割)。
🔹 方法2: for ループ(確実に動作)
動作原理
-
for file in *.jpg
でシェルがカレントディレクトリの*.jpg
をすべてリストアップ(メモリに一時保存)。 -
num=${file%.jpg}
でファイル名を数値に変換。 -
(num - 129) % 3 == 0
の判定で残すべきかチェック。 -
rm "$file"
で個別に削除。
メモリの使い方
-
ファイルリストの保存:
*.jpg
のリストはシェルのメモリ(ヒープ領域)に一時保存される。 -
ループ処理:
1ファイルずつ処理するため、メモリ使用量は低く抑えられる。 -
判定処理:
単一の整数演算のみで、CPU負荷は軽微。
メリット
- ✅ 処理の流れが明確で、予期しないエラーが出にくい。
- ✅ メモリをほとんど使わず、大量のファイルでも確実に動作する。
- ✅ 1ファイルずつ処理するので安全性が高い。
デメリット
- ❌ 1ファイルずつ
rm
を実行するため、処理速度が遅い。 - ❌
for file in *.jpg
の展開時に、大量のファイルがあるとメモリ不足になる可能性がある(数十万ファイル以上の場合)。
🔹 方法3: mv を使って安全に削除
動作原理
-
mkdir keep
で一時フォルダを作成。 -
for i in $(seq 129 3 4865)
で保存対象のファイル名を生成。 -
mv "$(printf "%04d.jpg" $i)" keep/ 2>/dev/null
で該当ファイルのみを移動。 -
rm *.jpg
で、残った不要なファイルを一括削除。 -
mv keep/* .
で保存対象ファイルを元に戻し、rmdir keep
で一時フォルダを削除。
メモリの使い方
-
mv の利用:
削除対象ファイルを事前に選別して移動するため、削除処理の安全性が向上。 -
リスト処理:
for
ループとseq
によるリスト生成のみで、CPU・メモリ負荷は非常に低い。 -
一括削除:
rm *.jpg
により一括実行するため、個別削除より高速。
メリット
- ✅ 直接
rm
を実行しないため、誤削除のリスクが低減される。 - ✅ 一時フォルダに移動するため、削除前にダブルチェックが可能。
- ✅ 方法2の安全性と、方法1の高速性を兼ね備えている。
デメリット
- ❌ 一時的なファイル移動が発生するため、ストレージの書き込み速度に依存する。
- ❌ 大量のファイル(数十万以上)の場合、一時フォルダへの移動に時間がかかる可能性がある。
まとめ
この記事は、特定のファイル削除処理における3つの手法について、その動作原理とメモリ使用量、各方法のメリット・デメリットを詳しく解説しています。
-
方法1 (find + grep):
- ストリーム処理で高速かつメモリ効率良く実行可能。
-
方法2 (for ループ):
- シンプルで安全だが、1ファイルずつ処理するため速度が遅い。
-
方法3 (mv を利用した安全削除):
- 移動操作を組み合わせることで、誤削除リスクを下げつつ高速化を図る。