HapInS Developers Blog

HapInSが提供するエンジニアリングの情報サイト

【解説】7zやzipからCHDを作成!Bashスクリプトで自動化し、時間を節約する方法

HapInSアドベントカレンダー2024、16日目!王将の豚キムチを愛してやまないponです!

この記事では、LinuxMacでディスクイメージ(例:.cueおよび.bin形式)を圧縮形式(.chdファイル)に変換する作業を自動化するBashスクリプトについて詳しく解説します。

スクリプトの主な機能

今回のスクリプトは、以下のようなタスクを自動で処理する便利なツールです。

  • 圧縮ファイル(.7zや.zip形式)を検索し展開する。
  • 展開したファイルの中から、.cueと.binを検出してリンクを修正。
  • .cueファイルをもとに、CHDファイルを生成する。
  • 一時的な作業ディレクトリを自動的にクリーンアップ。
    ※豆知識: CHD(Compressed Hunks of Data)ファイルは、古いディスクイメージの圧縮形式として非常に便利です。CHDファイルを使うことで、ストレージの節約や処理速度の向上が期待できます。

注意: 本スクリプトは、DVDリーダーなどを利用し既に合法的に所有しているご自身のディスクイメージファイルの処理を目的としています。違法に入手したディスクイメージ、ゲームイメージを使用したり、他人の著作権を侵害するような行為は避けてください。

注意点:依存ツールの確認

スクリプト実行時にエラーが出てしまいますので、実行前に、7z、unzip、chdmanがインストールされているかチェックしましょう。

Bashスクリプト全文

#!/bin/bash

# 現在のディレクトリとサブディレクトリ内の .7z と .zip ファイルをループ処理
find . -type f \( -name "*.7z" -o -name "*.zip" \) | while read -r file; do
  # ファイル拡張子を取得
  ext="${file##*.}"
  base_name=$(basename "$file")
  echo "Processing file: $base_name"

  # 一時ディレクトリを作成
  temp_dir=$(mktemp -d)

  # アーカイブファイルを展開
  if [[ "$ext" == "7z" ]]; then
    if ! 7z x "$file" -o"$temp_dir"; then
      echo "Error extracting 7z file: $file"
      rm -rf "$temp_dir"
      continue
    fi
  elif [[ "$ext" == "zip" ]]; then
    if ! unzip "$file" -d "$temp_dir"; then
      echo "Error extracting zip file: $file"
      rm -rf "$temp_dir"
      continue
    fi
  else
    echo "Unsupported file type: $file"
    rm -rf "$temp_dir"
    continue
  fi

  # 元のアーカイブがあるディレクトリを取得
  output_dir=$(dirname "$file")

  # 展開されたディレクトリから .cue ファイルを検索
  cue_files=$(find "$temp_dir" -type f -name "*.cue")
  if [[ -z "$cue_files" ]]; then
    echo "No .cue files found in $base_name, skipping."
    rm -rf "$temp_dir"
    continue
  fi

  echo "Found .cue files in $base_name, starting CHD conversion..."

  echo "$cue_files" | while read -r cue_file; do
    # 対応する .bin ファイルを検索
    bin_file=$(find "$(dirname "$cue_file")" -type f -name "*.bin" | head -n 1)
    if [[ -z "$bin_file" ]]; then
      echo "No .bin file found for $cue_file. Skipping."
      continue
    fi

    # .cue ファイルを修正
    sed -i "s|FILE \".*\"|FILE \"$(basename "$bin_file")\"|" "$cue_file"

    # .cue ファイルを元に CHD ファイルを作成
    chd_output="${output_dir}/$(basename "${cue_file%.cue}.chd")"
    if [[ ! -f "$chd_output" ]]; then
      if ! chdman createcd -i "$cue_file" -o "$chd_output"; then
        echo "Error creating CHD from $cue_file."
        rm -rf "$temp_dir"
        continue 2  # 次のファイルへスキップ
      fi
      echo "Created CHD file: $chd_output"
    else
      echo "CHD file already exists: $chd_output"
    fi
  done

  # 一時ディレクトリを削除(元のアーカイブは削除しない)
  rm -rf "$temp_dir"
done

echo "Done!"

スクリプトの仕組みと解説

圧縮ファイルの検索と展開

まず、findコマンドを使用し、現在のディレクトリおよびそのサブディレクトリ内から.7zや.zip形式のファイルを検索します。それぞれのファイルを一時ディレクトリに展開し、次のステップに進みます。

find . -type f \( -name "*.7z" -o -name "*.zip" \)

.cueおよび.binファイルの検出

展開されたディレクトリから.cueファイルを探し、それに関連する.binファイルが存在するか確認します。

cue_files=$(find "$temp_dir" -type f -name "*.cue")
bin_file=$(find "$(dirname "$cue_file")" -type f -name "*.bin" | head -n 1)

.cueファイルの修正

.cueファイル内の記述を修正し、正しい.binファイル名を参照させます。この修正はsedコマンドで行われます。

sed -i "s|FILE \".*\"|FILE \"$(basename "$bin_file")\"|" "$cue_file"

CHDファイルの作成

chdmanコマンドを使用して、修正済みの.cueファイルからCHDファイルを生成します。

chdman createcd -i "$cue_file" -o "$chd_output"

まとめ

このBashスクリプトは、ディスクイメージ変換の手間を大幅に削減する便利なツールです。効率的なデータ管理が可能になり、ファイルを扱う作業の負担を軽減します。この記事を参考にして、LinuxMacなどの環境でスクリプトを活用してみてください!