Node.jsスクリプトを使用してファイルを自動搬送する

最近、特定のディレクトリ内のファイルを他のディレクトリに搬送する必要がありました。具体的には、ユーザーが搬送する必要があるファイルがa.txtである場合、現在のディレクトリ内に存在する他のプレフィックスを含むa.txtファイル(例:gz-a.txtdj-a.txtny-a.txtなど)を見つけて、これらのファイルを対応するターゲットディレクトリに搬送し、a.txtにリネームする必要があります。搬送後、ソースディレクトリ内の元のファイルを削除します。

ディレクトリ構造の例

ソースディレクトリ(ユーザーが入力するソースディレクトリパス、例:/www/zk-prac/aa/bb/cc)には、以下のファイルが含まれている場合があります:

1
/www/zk-prac/aa/bb/cc/a.txt
2
/www/zk-prac/aa/bb/cc/gz-a.txt
3
/www/zk-prac/aa/bb/cc/dj-a.txt
4
/www/zk-prac/aa/bb/cc/ny-a.txt

ターゲット基本ディレクトリ(ユーザーが入力するターゲット基本ディレクトリパス、例:/www/)の構造は以下のようになります:

1
/www/gz-prac/aa/bb/cc/
2
/www/dj-prac/aa/bb/cc/
3
/www/ny-prac/aa/bb/cc/

この例では、スクリプトは/www/zk-prac/aa/bb/cc/gz-a.txt/www/gz-prac/aa/bb/cc/a.txtに、/www/zk-prac/aa/bb/cc/dj-a.txt/www/dj-prac/aa/bb/cc/a.txtに、そして/www/zk-prac/aa/bb/cc/ny-a.txt/www/ny-prac/aa/bb/cc/a.txtに搬送し、ソースファイルを削除する必要があります。

スクリプトの実装

2つの依存パッケージをインストールします:

Terminal window
1
pnpm add inquirer fs-extra

ESモジュールを使用しているため、package.jsonに以下の宣言を追加する必要があります:

1
"type": "module",

以下は、この要件を実現するNode.jsスクリプトです:

1
import fs from "fs";
2
import path from "path";
3
import fse from "fs-extra";
4
import inquirer from "inquirer";
5
6
async function main() {
7
// ユーザーにソースディレクトリのパスを入力させる
8
const { sourceDir } = await inquirer.prompt([
9
{
10
type: "input",
11
name: "sourceDir",
12
message: "ソースディレクトリのパスを入力してください:",
13
validate: (input) =>
14
fs.existsSync(input)
15
? true
16
: "ディレクトリが存在しません、有効なパスを入力してください",
17
},
18
]);
19
20
// ユーザーにベースターゲットディレクトリのパスを入力させる
21
const { baseTargetDir } = await inquirer.prompt([
22
{
23
type: "input",
24
name: "baseTargetDir",
25
message: "ベースターゲットディレクトリのパスを入力してください:",
26
validate: (input) =>
27
fs.existsSync(input)
28
? true
29
: "ディレクトリが存在しません、有効なパスを入力してください",
30
},
31
]);
32
33
// ユーザーにファイル名を入力させる
34
const { targetFileName } = await inquirer.prompt([
35
{
36
type: "input",
37
name: "targetFileName",
38
message: "移動するファイル名を入力してください(例: a.txt):",
39
validate: (input) => (input ? true : "ファイル名は空白にできません"),
40
},
41
]);
42
43
// ソースディレクトリ内のすべてのファイルを取得
44
const files = fs.readdirSync(sourceDir);
45
46
// プレフィックスを含むすべてのターゲットファイルを見つける
47
const matchedFiles = files.filter(
48
(file) => file.endsWith(targetFileName) && file !== targetFileName,
49
);
50
51
if (matchedFiles.length === 0) {
52
console.log("一致するプレフィックスファイルが見つかりませんでした。");
53
return;
54
}
55
56
// 相対パスを計算
57
const relativePath = path.relative(baseTargetDir, sourceDir);
58
59
// ベースターゲットディレクトリから除外するディレクトリを見つけて除外する
60
const targetPathParts = relativePath.split(path.sep);
61
targetPathParts.shift(); // 最初のディレクトリを削除
62
63
// 実際のターゲットディレクトリのパスを計算
64
const subDir = targetPathParts.join(path.sep);
65
66
// 各一致するターゲットディレクトリにファイルを移動する
67
for (const file of matchedFiles) {
68
const prefix = file.split("-")[0];
69
const targetDirs = fs
70
.readdirSync(baseTargetDir)
71
.filter((dir) => dir.startsWith(prefix));
72
73
for (const targetDir of targetDirs) {
74
const targetPath = path.join(baseTargetDir, targetDir, subDir);
75
const sourceFilePath = path.join(sourceDir, file);
76
const targetFilePath = path.join(targetPath, targetFileName);
77
78
try {
79
await fse.ensureDir(targetPath);
80
await fse.copy(sourceFilePath, targetFilePath);
81
console.log(`ファイル ${file} を ${targetFilePath} に移動しました`);
82
await fse.remove(sourceFilePath);
83
console.log(`ソースファイル ${sourceFilePath} を削除しました`);
84
} catch (err) {
85
console.error(
86
`ファイルの移動または削除中にエラーが発生しました: ${err}`,
87
);
88
}
89
}
90
}
91
}
92
93
main().catch(console.error);

使用方法

  1. スクリプトを実行すると、まずユーザーにソースディレクトリパスの入力を求められます。
  2. 次に、ターゲット基本ディレクトリパスの入力を求められます。
  3. ユーザーは搬送するファイル名(例:a.txt)を入力します。
  4. スクリプトはソースディレクトリ内のすべてのプレフィックスを含むターゲットファイルを見つけ、それらを対応するターゲットディレクトリに搬送し、ファイルをユーザー指定のファイル名にリネームし、ソースファイルを削除します。