39

I want to delete several files from a directory, matching a regex. Something like this:

// WARNING: not real code require('fs').unlink(/script\.\d+\.js$/); 

Since unlink doesn't support regexes, I'm using this instead:

var fs = require('fs'); fs.readdir('.', (error, files) => { if (error) throw error; files.filter(name => /script\.\d+\.js$/.test(name)).forEach(fs.unlink); }); 

which works, but IMO is a little more complex than it should be.


Is there a better built-in way to delete files that match a regex (or even just use wildcards)?

4
  • 2
    Seems reasonable. What makes it seem overly complex? Commented Feb 17, 2013 at 3:50
  • 3
    @loganfsmyth - Because I want it to be simpler? :) Commented Feb 17, 2013 at 3:51
  • I suspect the downvote is because you're basically asking a question and answering it yourself. Personally, I think your code is nice and rather concise. Too much more concise and it might actually start obscuring the functionality. I'd just modularize it, passing the regex and the directory name as arguments. An upvote for you, sir! Commented Feb 17, 2013 at 4:30
  • 1
    @WillNelson - I'm not asking for anybody to refactor my code (I would've posted to codereview for that). I'm asking if there's a better built-in way to accomplish this. Commented Feb 17, 2013 at 4:34

4 Answers 4

41

No there is no globbing in the Node libraries. If you don't want to pull in something from NPM then not to worry, it just takes a line of code. But in my testing the code provided in other answers mostly won't work. So here is my code fragment, tested, working, pure native Node and JS.

let fs = require('fs') const path = './somedirectory/' let regex = /[.]txt$/ fs.readdirSync(path) .filter(f => regex.test(f)) .map(f => fs.unlinkSync(path + f)) 
Sign up to request clarification or add additional context in comments.

8 Comments

this should be the best answer. copy, paste, tune regex, and files I want to delete is deleted.
you have path and dpath, is that supposed to be different?
@JoãoPimentelFerreira: oops, sorry, fixed.
I think forEach is more appropriate than map in this example
@mracette: Why? Feel free to provide your own answer and explain why it's better. I don't see it.
|
13

You can look into glob https://npmjs.org/package/glob

require("glob").glob("*.txt", function (er, files) { ... }); //or files = require("glob").globSync("*.txt"); 

glob internally uses minimatch. It works by converting glob expressions into JavaScript RegExp objects. https://github.com/isaacs/minimatch

You can do whatever you want with the matched files in the callback (or in case of globSync the returned object).

2 Comments

+1 Thank you, but I'm looking for a built-in solution; I don't think this justifies introducing another dependency to my project. If there's no better native solution, I think the code posted will serve me just fine.
as a follow up (albeit a few months late), wanting to do things using "built in functions" in Node.js is not quite the Node.js way. It is bundled with npm specifically because it is incredibly easy to add a new library using npm install glob --save (in this case). For Node.js development, "through npm" and "built in" are virtually the same thing.
1

I have a very simple solution to do this. Read the directory in node.js using fs.readdir API. This will give an array of all the files in the directory. Once you have that array, iterate over it using for loop, apply regex. The below code will delete all files starting with "en" and extension ".js"

fs.readdir('.', (err, files)=>{ for (var i = 0, len = files.length; i < len; i++) { var match = files[i].match(/en.*.js/); if(match !== null) fs.unlink(match[0]); } }); 

1 Comment

How is this any different than the code in the question?
0

The answer could depend on your environment. It looks like you are running on node.js. A quick perusal of the node.js documentation suggests there is no "built in" way to do this, i.e., there isn't a single function call that will do this for you. The next best thing might involve a small number of function calls. As I wrote in my comment, I don't think there's any easy way to make your suggested answer much briefer just relying on the standard node.js function calls. That is, if I were in your shoes, I would go with the solution you already suggested (though slightly cleaned up).

One alternative is to go to the shell, e.g.,

var exec = require('child_process').exec; exec('ls | grep "script[[:digit:]]\\\+.js" | xargs rm'); 

Personally, I would strongly prefer your offered solution over this gobbledygook, but maybe you're shooting for something different.

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.