使用nodejs复制文件夹,并在目标中已存在具有匹配名称的文件夹时为其名称添加后缀

时间:2018-01-23 07:22:45

标签: node.js directory shelljs

我正在调用Feathers JS API来复制包含一些文件的文件夹。假设我的文件夹名称是'Website1'

Linux的正常行为是,它将新文件夹名称附加为'Website1 copy',并进一步作为'Website1另一个副本''Website1 3rd复制',等等。

这可以通过ShellJS实现吗?

我的代码:

function after_clone_website(hook) {
  return new Promise((resolve, reject) => {
    let sourceProjectName = hook.params.query.sourceProjectName;
    let destinationProjectName = sourceProjectName + '_copy';

    let userDetailId = hook.params.query.userDetailId;

    let response = '';

    response = shell.cp('-Rf', config.path + userDetailId + '/' + 
        sourceProjectName, config.path + userDetailId + '/' +
        destinationProjectName);

    hook.result = response;
    resolve(hook)

  });
}

1 个答案:

答案 0 :(得分:0)

ShellJS不包含用于模拟Linux相同行为的内置逻辑。即要追加; ... copy ...另一个副本 ...第三个副本 ...第四个副本 etc ,当目标路径上的文件夹已存在且与正在复制的源文件夹同名时,为文件夹名称。

解决方案:

您可以使用带有test()选项的ShellJS -e方法来检查路径的每个潜在变体是否存在。如果确实存在,则运行您自己的自定义逻辑,以确定cp()方法中正确的目标路径值应该是什么。

该自定义逻辑应该是什么?

以下要点包含一个自定义copyDirAndRenameIfExists()函数,它接受两个参数;源文件夹的路径,以及目标文件夹的路径(与ShellJS cp()函数的工作方式非常相似)。

var path = require('path'),
    shell = require('shelljs');

/**
 * Copies a given source folder to a given destination folder.
 *
 * To avoid potentially overwriting an exiting destination folder, (i.e. in the
 * scenario whereby a folder already exists in the destination folder with the
 * same name as the source folder), the source folder will be renamed following
 * normal Linux behaviour. I.e. One of the following values will be appended as
 * appropriate: `copy`, `another copy`, `3rd copy`, `4th copy`, etc.
 *
 * @param {String} srcDir - Path to the source directory to copy.
 * @param {String} destDir - Path to the destination directory.
 * @returns {Object} Object returned from invoking the shelljs `cp()` method.
 */
function copyDirAndRenameIfExists(srcDir, destDir) {
    var dirName = path.basename(srcDir),
        newDirName = '',
        hasCopied = false,
        counter = 0,
        response = {};

    /**
     * Helper function suffixes cardinal number with relevent ordinal
     * number suffix. I.e. st, nd, rd, th
     * @param {Number} number - The number to suffix.
     * @returns {String} A number with its ordinal number suffix.
     */
    function addOrdinalSuffix(number) {
        var j = number % 10,
            k = number % 100;

        if (j === 1 && k !== 11) {
            return number + 'st';
        }
        if (j === 2 && k !== 12) {
            return number + 'nd';
        }
        if (j === 3 && k !== 13) {
            return number + 'rd';
        }
        return number + 'th';
    }

    /**
     * Helper function to get the appropriate folder name suffix.
     * @param {Number} num - The current loop counter.
     * @returns {String} The appropriate folder name suffix.
     */
    function getSuffix(number) {
        if (number === 1) {
            return ' copy';
        }
        if (number === 2) {
            return ' another copy';
        }
        return ' ' + addOrdinalSuffix(number) + ' copy';
    }

    /**
     * Helper function copies the source folder recursively to the destination
     * folder if the source directory does not already exist at the destination.
     */
    function copyDir(srcDir, destDir) {
        if (!shell.test('-e', destDir)) {
            response = shell.cp('-R', srcDir, destDir);
            hasCopied = true;
        }
    }

    // Continuously invokes the copyDir() function
    // until the source folder has been copied.
    do {
        if (counter === 0) {
            copyDir(srcDir, path.join(destDir, dirName));
        } else {
            newDirName = dirName + getSuffix(counter);
            copyDir(srcDir, path.join(destDir, newDirName));
        }
        counter += 1;

    } while (!hasCopied);

    return response;
}

实施

  1. copyDirAndRenameIfExists()函数从上面提供的要点(上面)添加到现有节点程序中。

  2. 确保您的require节点内置path模块(除了shelljs之外),在您的计划开始时(如果您不这样做)已经有了)。即添加以下内容:

  3.     var path = require('path');
    
    1. 最后通过更改问题中提供的代码行来调用自定义copyDirAndRenameIfExists()函数:

      response = shell.cp('-Rf', config.path + userDetailId + '/' +
          sourceProjectName, config.path + userDetailId + '/' + destinationProjectName);
      

      代替以下内容:

      response = copyDirAndRenameIfExists(
        path.join(config.path, userDetailId, sourceProjectName),
        path.join(config.path, userDetailId, destinationProjectName)
      };