モーリーのメモ

アプリ開発等(プログラミング、CG作成)、興味を持ったことを実践してまとめるブログです。

モーリーのメモ

match()とreplace()を使ってファイル名を変更する!(ちょっと対話型):Node.js

mmorley.hatenablog.com
 ↑の記事のプログラムの派生版です。
 
 文字の検索(match())や文字の置換(replace()関数)を使って、ファイル名を変更します。
 フォルダ内の複数のファイルからmatch()を使って対象のファイルを絞り込み、replace()で新しいファイル名を作成します。
 変更前には、変更内容を確認します。
 ユーザーに確認を取るための対話型処理については、冒頭の記事で説明しています。

使用環境

正規表現について

 match()とreplace()では、文字の検索に正規表現を使用します。
 正規表現については、下記のサイトが参考になります。
www.megasoft.co.jp
 作成した正規表現が正しく動作するか調べるには、下記のサイトが便利です。
www.regexr.com

作成したファイル名変更プログラム

 注意!:思わぬ動作をした時に、複数のファイル名を元に戻すのは大変なので、使用する前に、オリジナルはコピーして残しておいて下さい。

    var fs = require('fs'); // File System(Node API):ファイル操作
    var path = require('path'); // Path(Node API):パスの文字列操作
    var rl = require('readline'); // Readline(Node API):読み込み可能なストリームから1行ずつデータを読み込む
    
    var dirTarget = '/Users/ユーザ名/Desktop/Images '; // 処理対象のフォルダ
    
    // コマンドライン(ターミナル)の入出力の設定
    var rli = rl.createInterface({ // readline.Interfaceの設定
      input: process.stdin, // 読み込み可能なストリームに標準入力を設定
      output: process.stdout, // 書き込み可能なストリームに標準出力を設定
      prompt: 'y/n?: ' // プロンプトを設定
    });
    
    var count = 1;
    var files = fs.readdirSync(dirTarget); // 指定フォルダ内のファイル、サブフォルダのリストを取得
    var arFileData = []; // ファイル情報保持用の配列
    files.forEach(function(file){  
        // ファイル名が条件を満たすものだけを処理
        // ファイル名が'image'で始まらない場合、処理を抜ける
        // (^は先頭を表すメタ文字、末尾は$)
        if(file.match(/^image/) === null) return;
        // 新しいファイル名
        // ファイル名の先頭に'写真_'を付けて、'image'の文字を削除
        var newName = '写真_' + file.replace(/^image/, ''); 
        var fileData = {}; // 変更内容を保持
        fileData.fullPath = path.join(dirTarget, file); // 元のファイルのフルパス
        fileData.newFullPath = path.join(dirTarget, newName); // 新しいファイル名のフルパス
        arFileData.push(fileData); // 配列に追加
        // 変更内容を表示
        console.log(count++ + ':'); // カウント
        console.log('元:' + file); // 元のファイル名を表示
        console.log('新:' + newName); // 新しいファイル名を表示
    });
    
    rli.prompt(); // プロンプトを表示
    
    // 'line'イベント
    // コマンドライン(ターミナル)で『return』が押された時に発生
    // 引数のlineに入力された文字が入る
    rli.on('line', function(line){ 
        switch(line.trim().toLowerCase()) { // 空白文字を除去し、小文字に変換
            case 'y': 
                // 新しい名前に変更
                arFileData.forEach(function(fileData){
                    fs.renameSync( // ファイル名を変更
                        fileData.fullPath, // 一時退避用の名前(フルパス)
                        fileData.newFullPath // 新しい名前(フルパス)
                    );
                });
                console.log('complated!'); // 完了を表示
                rli.close(); // 対話終了
                break;
            case 'n':
                console.log('canceled!'); // キャンセルを表示
                rli.close(); // 対話終了
                break;  
            default:
                rli.prompt(); // 再度プロンプトを表示
                break;
        }
    });
    
    // 'close'イベント(下記の場合に発生)
    //  rl.close()が呼び出された時
    //  コマンドライン(ターミナル)で『control + c』が押された時
    //  コマンドライン(ターミナル)で『control + d』が押された時
    rli.on('close', function(){ 
        console.log('exit!'); // 完了を表示
        process.exit(0); // プログラムを終了
    });
    

使い方

  1. (元に戻せるようにコピーしてオリジナルを取っておく)
  2. 『var dirTarget = '/Users/ユーザ名/Desktop/Images';』で、対象のファイルを含むフォルダを指定する
  3. 『if(file.match(/^image/) === null) return;』で、対象ファイルを絞り込むための正規表現を作成
  4. 『var newName = '写真_' + file.replace(/^image/, ''); 』で、新しいファイル名を作成
  5. プログラムを実行

あとがき

 過去に適当につけたファイル名をまとめて付け直したかったので作成しました。
 めったに使わない処理のような気もしますが、、、