首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> .NET 網頁程式設計 >> ASP.NET 基礎 >> 關於ASP.NET

Comiket 下載檔案批次重命名:Ruby 與 C# 腳本實作

     編輯:關於ASP.NET

每逢 Comic Market(Comiket)大展期間,下載回來的同人誌、周邊檔案命名格式五花八門,若直接依檔名排序瀏覽極為不便。這時候就得祭出批次重命名腳本。筆者習慣用 Ruby 的 irb 互動環境快速撰寫一次性腳本,這次整理出的腳本可在多個分類目錄下通用,特此記錄備查。

腳本功能與規則

目標檔名格式為 (Cxx)(item_type)[circle_name] item_name,腳本會將前綴標籤之間的多餘空格移除,並確保標籤整體與後方檔名之間僅保留一個空格。普通檔案與目錄皆為重命名對象;不符合「兩組圓括號 + 一組方括號」前綴格式的項目將被略過。筆者通常先用另一支腳本將各欄位順序調整為上述標準格式,再統一執行去空格動作。

限制與已知問題

  • 若檔名包含目前系統 Locale 無法顯示的字元,該檔案重命名會失敗(錯誤輸出至 stderr),但不影響後續項目處理。此類特殊字元檔案較少,建議事後手動修正。
  • Ruby 1.8 的編碼處理有缺陷;Ruby 1.9 雖支援 Unicode,但在執行檔案系統操作時仍可能出現編碼問題,後續再嘗試排查。

Ruby 實作

#!/usr/bin/env ruby
def reformat_comiket_folder(dir='.')
  Dir.entries(dir).each do |p|
    begin
      if p =~ /^\(([^)]+)\)\s*\(([^)]+)\)\s*\[([^\]]+)\]\s*(.+)$/
        File.rename p, "(#{$1})(#{$2})[#{$3}] #{$4}"
      end
    rescue SystemCallError
      $stderr.puts 'IO failed: ' + $!
    end
  end
end

if __FILE__ == $0
  reformat_comiket_folder ARGV[0] || '.'
end

C# 移植版(.NET Framework 3.5 SP1)

為徹底解決編碼問題,改以 C# 實作相同邏輯:

using System;
using System.IO;
using System.Linq;
using System.Text.RegularExpressions;

sealed class ReformatComiketFiles {
  static bool TryGetRenameName(
    Regex pattern, string input, string format,
    out string result
  ) {
    var match = pattern.Match(input);
    if (match.Success) {
      var str = string.Format(format,
        match.Groups.Cast<Group>().Skip(1).Select(g => g.Value).ToArray());
      result = str;
      return str != input;
    } else {
      result = input;
      return false;
    }
  }

  static void Main(string[] args) {
    DirectoryInfo root = (0 < args.Length)
      ? new DirectoryInfo(args[0])
      : new DirectoryInfo(Environment.CurrentDirectory);

    var pattern = new Regex(@"^\(([^)]+)\)\s*\(([^)]+)\)\s*\[([^\]]+)\]\s*(.+)$");

    foreach (var dir in root.GetDirectories()) {
      string dest = null;
      if (TryGetRenameName(pattern, dir.Name, "({0})({1})[{2}] {3}", out dest)) {
        Console.WriteLine(dest);
        dir.MoveTo(Path.Combine(dir.Parent.FullName, dest));
      }
    }
    foreach (var file in root.GetFiles()) {
      string dest = null;
      if (TryGetRenameName(pattern, file.Name, "({0})({1})[{2}] {3}", out dest)) {
        Console.WriteLine(dest);
        file.MoveTo(Path.Combine(file.DirectoryName, dest));
      }
    }
  }
}

實測兩版腳本均能正常運作。C# 版本得益於 .NET 處理 Unicode 的完善支援,不再受編碼困擾,適合長期維護使用。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved