Automatically Move Files Using a Node.js Script
- 559Words
- 3Minutes
- 19 Jul, 2024
Recently, I encountered a requirement to move certain files from a specified directory to other directories. Specifically, suppose the user needs to move a file named a.txt. We need to find other files in the current directory that include the prefix a.txt, such as gz-a.txt, dj-a.txt, ny-a.txt, etc., and then move these files to the corresponding target directories, renaming them to a.txt. After moving, the original files in the source directory should be deleted.
Example Directory Structure
The source directory (user-provided source directory path, e.g., /www/zk-prac/aa/bb/cc) might contain the following files:
1/www/zk-prac/aa/bb/cc/a.txt2/www/zk-prac/aa/bb/cc/gz-a.txt3/www/zk-prac/aa/bb/cc/dj-a.txt4/www/zk-prac/aa/bb/cc/ny-a.txtThe basic target directory (user-provided target basic directory path, e.g., /www/) has the following structure:
1/www/gz-prac/aa/bb/cc/2/www/dj-prac/aa/bb/cc/3/www/ny-prac/aa/bb/cc/In this example, the script needs to move /www/zk-prac/aa/bb/cc/gz-a.txt to /www/gz-prac/aa/bb/cc/a.txt, /www/zk-prac/aa/bb/cc/dj-a.txt to /www/dj-prac/aa/bb/cc/a.txt, and /www/zk-prac/aa/bb/cc/ny-a.txt to /www/ny-prac/aa/bb/cc/a.txt while deleting the source files.
Script Implementation
Install two dependencies:
1pnpm add inquirer fs-extraSince ES Module is being used, you need to add the following declaration to package.json:
1"type": "module",Here is the Node.js script to achieve this requirement:
1import fs from "fs";2import path from "path";3import fse from "fs-extra";4import inquirer from "inquirer";5
6async function main() {7  // Ask the user to input the source directory path8  const { sourceDir } = await inquirer.prompt([9    {10      type: "input",11      name: "sourceDir",12      message: "Please enter the source directory path:",13      validate: (input) =>14        fs.existsSync(input)15          ? true16          : "Directory does not exist, please enter a valid path",17    },18  ]);19
20  // Ask the user to input the base target directory path21  const { baseTargetDir } = await inquirer.prompt([22    {23      type: "input",24      name: "baseTargetDir",25      message: "Please enter the base target directory path:",26      validate: (input) =>27        fs.existsSync(input)28          ? true29          : "Directory does not exist, please enter a valid path",30    },31  ]);32
33  // Ask the user to input the filename34  const { targetFileName } = await inquirer.prompt([35    {36      type: "input",37      name: "targetFileName",38      message: "Please enter the filename to move (e.g., a.txt):",39      validate: (input) => (input ? true : "Filename cannot be empty"),40    },41  ]);42
43  // Get all files in the source directory44  const files = fs.readdirSync(sourceDir);45
46  // Find all target files with prefixes47  const matchedFiles = files.filter(48    (file) => file.endsWith(targetFileName) && file !== targetFileName,49  );50
51  if (matchedFiles.length === 0) {52    console.log("No matching prefix files found.");53    return;54  }55
56  // Calculate the relative path57  const relativePath = path.relative(baseTargetDir, sourceDir);58
59  // Find and exclude directories to be excluded from the base target directory60  const targetPathParts = relativePath.split(path.sep);61  targetPathParts.shift(); // Remove the first directory62
63  // Calculate the actual target directory path64  const subDir = targetPathParts.join(path.sep);65
66  // Move files to each matching target directory67  for (const file of matchedFiles) {68    const prefix = file.split("-")[0];69    const targetDirs = fs70      .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(`Moved ${file} to ${targetFilePath}`);82        await fse.remove(sourceFilePath);83        console.log(`Deleted source file ${sourceFilePath}`);84      } catch (err) {85        console.error(`Error moving or deleting file: ${err}`);86      }87    }88  }89}90
91main().catch(console.error);Usage Instructions
- When running the script, it will first ask the user for the source directory path.
- Then it will ask the user for the target basic directory path.
- The user will then input the file name to be moved (e.g., a.txt).
- The script will find all target files with the prefix in the source directory and move them to the corresponding target directories, renaming the files to the user-specified file name and deleting the source files.
 
   
  