Is there a simple way to move all the files in a directory up to its parent directory then delete the directory?
I'm doing a zip extraction and the source zip contains a root folder called archive
, so when I extract I get extract_path/archive/
, but I'd like to just extract the contents of archive
directly to extract_path
.
I thought this would be simple rename, but the following is throwing a "There is a file in the way" error message.
fs.renameSync(extractPath + "/archive", extractPath)
In this tutorial, we are going to learn about how to move the files from one directory to another directory in Node.js. Node.js has a built-in file system module, which has an fs.rename () method that helps us to asynchronously move a file from one directory to another.
Let's get the files now. The most familiar way to Node.js get all files in directory is to use the fs (file system) module with methods like readdir () and readdirSync (). You can asynchronously list files in a directory using the readdir () method.
The Node.js fs core module provides many handy methods you can use to work with folders. Use fs.access () (and its promise-based fsPromises.access () counterpart) to check if the folder exists and Node.js can access it with its permissions. Use fs.mkdir () or fs.mkdirSync () or fsPromises.mkdir () to create a new folder.
Node.js has a built-in file system module, which has an fs.rename () method that helps us to asynchronously move a file from one directory to another. Here is an example:
Non of the answers work for me, I looked deep in mv's code and found my solution:
I move folder/subfolder
to folder
, so the folder already exists.
mv(oldPath, newPath, {mkdirp: false, clobber: false}, (err) => {
if (err) {
throw err;
}
});
Remember if the filename already exists in parent folder it will overwrite by file inside subfolder.
The selected answer does not work:
var mv = require('mv');
var extractPath = 'E:\\tmp\\dir';
mv(extractPath + "\\sub", extractPath, {mkdirp: true}, console.error);
It errors with:
{ Error: EPERM: operation not permitted, rename 'E:\tmp\dir\sub' -> 'E:\tmp\dir'
at Error (native)
errno: -4048,
code: 'EPERM',
syscall: 'rename',
path: 'E:\\tmp\\dir\\sub',
dest: 'E:\\tmp\\dir' }
Use fs-extra instead of mv:
var fs = require('fs-extra');
var extractPath = 'E:\\tmp\\dir';
fs.move(extractPath + "\\sub", extractPath, console.error);
My file structure is like this before the move:
E:\tmp\dir
> sub
> doc.txt
And like this after the move:
E:\tmp\dir
> doc.txt
UPDATE:
While the above works on Windows, on Linux I get the same error even when using fs-extra. The below is a manual fix for this, by individually moving each child of the subdirectory up to the parent. If a child move fails, then it will revert any other successful moves back to the original location in the subdirectory.
var fs = require('fs-extra')
var Promise = require('promise');
var path = require('path');
var promiseAllWait = function(promises) {
// this is the same as Promise.all(), except that it will wait for all promises to fulfill before rejecting
var all_promises = [];
for(var i_promise=0; i_promise < promises.length; i_promise++) {
all_promises.push(
promises[i_promise]
.then(function(res) {
return { res: res };
}).catch(function(err) {
return { err: err };
})
);
}
return Promise.all(all_promises)
.then(function(results) {
return new Promise(function(resolve, reject) {
var is_failure = false;
var i_result;
for(i_result=0; i_result < results.length; i_result++) {
if (results[i_result].err) {
is_failure = true;
break;
} else {
results[i_result] = results[i_result].res;
}
}
if (is_failure) {
reject( results[i_result].err );
} else {
resolve(results);
}
});
});
};
var movePromiser = function(from, to, records) {
return fs.move(from, to)
.then(function() {
records.push( {from: from, to: to} );
});
};
var moveDir = function(from_dir, to_dir) {
return fs.readdir(from_dir)
.then(function(children) {
return fs.ensureDir(to_dir)
.then(function() {
var move_promises = [];
var moved_records = [];
var child;
for(var i_child=0; i_child < children.length; i_child++) {
child = children[i_child];
move_promises.push(movePromiser(
path.join(from_dir, child),
path.join(to_dir, child),
moved_records
));
}
return promiseAllWait(move_promises)
.catch(function(err) {
var undo_move_promises = [];
for(var i_moved_record=0; i_moved_record < moved_records.length; i_moved_record++) {
undo_move_promises.push( fs.move(moved_records[i_moved_record].to, moved_records[i_moved_record].from) );
}
return promiseAllWait(undo_move_promises)
.then(function() {
throw err;
});
});
}).then(function() {
return fs.rmdir(from_dir);
});
});
};
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With