使用 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 並刪除源文件。

腳本實現

安裝兩個依賴包:

Terminal window
1
pnpm add inquirer fs-extra

由於使用的是ES Module,你需要在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) ? true : "目錄不存在,請輸入一個有效的路徑",
15
},
16
]);
17
18
// 詢問用戶輸入目標基本目錄路徑
19
const { baseTargetDir } = await inquirer.prompt([
20
{
21
type: "input",
22
name: "baseTargetDir",
23
message: "請輸入目標基本目錄路徑:",
24
validate: (input) =>
25
fs.existsSync(input) ? true : "目錄不存在,請輸入一個有效的路徑",
26
},
27
]);
28
29
// 詢問用戶輸入文件名
30
const { targetFileName } = await inquirer.prompt([
31
{
32
type: "input",
33
name: "targetFileName",
34
message: "請輸入要搬運的文件名(例如 a.txt):",
35
validate: (input) => (input ? true : "文件名不能為空"),
36
},
37
]);
38
39
// 獲取源目錄中的所有文件
40
const files = fs.readdirSync(sourceDir);
41
42
// 找到所有包含前綴的目標文件
43
const matchedFiles = files.filter(
44
(file) => file.endsWith(targetFileName) && file !== targetFileName,
45
);
46
47
if (matchedFiles.length === 0) {
48
console.log("未找到匹配的前綴文件。");
49
return;
50
}
51
52
// 計算相對路徑
53
const relativePath = path.relative(baseTargetDir, sourceDir);
54
55
// 查找並排除目標基本目錄中需要排除的目錄
56
const targetPathParts = relativePath.split(path.sep);
57
targetPathParts.shift(); // 移除第一個目錄
58
59
// 計算實際的目標目錄路徑
60
const subDir = targetPathParts.join(path.sep);
61
62
// 搬運文件到每個匹配的目標目錄
63
for (const file of matchedFiles) {
64
const prefix = file.split("-")[0];
65
const targetDirs = fs
66
.readdirSync(baseTargetDir)
67
.filter((dir) => dir.startsWith(prefix));
68
69
for (const targetDir of targetDirs) {
70
const targetPath = path.join(baseTargetDir, targetDir, subDir);
71
const sourceFilePath = path.join(sourceDir, file);
72
const targetFilePath = path.join(targetPath, targetFileName);
73
74
try {
75
await fse.ensureDir(targetPath);
76
await fse.copy(sourceFilePath, targetFilePath);
77
console.log(`已搬運 ${file} 到 ${targetFilePath}`);
78
await fse.remove(sourceFilePath);
79
console.log(`已刪除源文件 ${sourceFilePath}`);
80
} catch (err) {
81
console.error(`搬運或刪除文件時出錯: ${err}`);
82
}
83
}
84
}
85
}
86
87
main().catch(console.error);

使用說明

  1. 運行腳本時,首先會詢問用戶輸入源目錄路徑。
  2. 然後詢問用戶輸入目標基本目錄路徑。
  3. 用戶輸入要搬運的文件名(例如 a.txt)。
  4. 腳本會在源目錄中找到所有包含前綴的目標文件,並將它們搬運到對應的目標目錄,同時將文件重命名為用戶指定的文件名,並刪除源文件。