find files by extension, *.html under a folder in nodejs

后端 未结 14 695
隐瞒了意图╮
隐瞒了意图╮ 2020-12-07 23:57

I\'d like to find all *.html files in src folder and all its sub folders using nodejs. What is the best way to do it?

var folder = \'/project1/src\';
var ex         


        
相关标签:
14条回答
  • 2020-12-08 00:18

    You can use OS help for this. Here is a cross-platform solution:

    1. The bellow function uses ls and dir and does not search recursively but it has relative paths

    var exec = require('child_process').exec;
    function findFiles(folder,extension,cb){
        var command = "";
        if(/^win/.test(process.platform)){
            command = "dir /B "+folder+"\\*."+extension;
        }else{
            command = "ls -1 "+folder+"/*."+extension;
        }
        exec(command,function(err,stdout,stderr){
            if(err)
                return cb(err,null);
            //get rid of \r from windows
            stdout = stdout.replace(/\r/g,"");
            var files = stdout.split("\n");
            //remove last entry because it is empty
            files.splice(-1,1);
            cb(err,files);
        });
    }
    
    findFiles("folderName","html",function(err,files){
        console.log("files:",files);
    })
    

    2. The bellow function uses find and dir, searches recursively but on windows it has absolute paths

    var exec = require('child_process').exec;
    function findFiles(folder,extension,cb){
        var command = "";
        if(/^win/.test(process.platform)){
            command = "dir /B /s "+folder+"\\*."+extension;
        }else{
            command = 'find '+folder+' -name "*.'+extension+'"'
        }
        exec(command,function(err,stdout,stderr){
            if(err)
                return cb(err,null);
            //get rid of \r from windows
            stdout = stdout.replace(/\r/g,"");
            var files = stdout.split("\n");
            //remove last entry because it is empty
            files.splice(-1,1);
            cb(err,files);
        });
    }
    
    findFiles("folder","html",function(err,files){
        console.log("files:",files);
    })
    
    0 讨论(0)
  • 2020-12-08 00:20

    my two pence, using map in place of for-loop

    var path = require('path'), fs = require('fs');
    
    var findFiles = function(folder, pattern = /.*/, callback) {
      var flist = [];
    
      fs.readdirSync(folder).map(function(e){ 
        var fname = path.join(folder, e);
        var fstat = fs.lstatSync(fname);
        if (fstat.isDirectory()) {
          // don't want to produce a new array with concat
          Array.prototype.push.apply(flist, findFiles(fname, pattern, callback)); 
        } else {
          if (pattern.test(fname)) {
            flist.push(fname);
            if (callback) {
              callback(fname);
            }
          }
        }
      });
      return flist;
    };
    
    // HTML files   
    var html_files = findFiles(myPath, /\.html$/, function(o) { console.log('look what we have found : ' + o} );
    
    // All files
    var all_files = findFiles(myPath);
    
    0 讨论(0)
  • 2020-12-08 00:21

    Take a look into file-regex

    let findFiles = require('file-regex')
    let pattern = '\.js'
    
    findFiles(__dirname, pattern, (err, files) => {  
       console.log(files);
    })
    

    This above snippet would print all the js files in the current directory.

    0 讨论(0)
  • 2020-12-08 00:22

    The following code does a recursive search inside ./ (change it appropriately) and returns an array of absolute file names ending with .html

    var fs = require('fs');
    var path = require('path');
    
    var searchRecursive = function(dir, pattern) {
      // This is where we store pattern matches of all files inside the directory
      var results = [];
    
      // Read contents of directory
      fs.readdirSync(dir).forEach(function (dirInner) {
        // Obtain absolute path
        dirInner = path.resolve(dir, dirInner);
    
        // Get stats to determine if path is a directory or a file
        var stat = fs.statSync(dirInner);
    
        // If path is a directory, scan it and combine results
        if (stat.isDirectory()) {
          results = results.concat(searchRecursive(dirInner, pattern));
        }
    
        // If path is a file and ends with pattern then push it onto results
        if (stat.isFile() && dirInner.endsWith(pattern)) {
          results.push(dirInner);
        }
      });
    
      return results;
    };
    
    var files = searchRecursive('./', '.html'); // replace dir and pattern
                                                    // as you seem fit
    
    console.log(files);
    
    0 讨论(0)
  • 2020-12-08 00:22

    I just noticed, you are using sync fs methods, that might block you application, here is a promise-based async way using async and q, you can execute it with START=/myfolder FILTER=".jpg" node myfile.js, assuming you put the following code in a file called myfile.js:

    Q = require("q")
    async = require("async")
    path = require("path")
    fs = require("fs")
    
    function findFiles(startPath, filter, files){
        var deferred;
        deferred = Q.defer(); //main deferred
    
        //read directory
        Q.nfcall(fs.readdir, startPath).then(function(list) {
            var ideferred = Q.defer(); //inner deferred for resolve of async each
            //async crawling through dir
            async.each(list, function(item, done) {
    
                //stat current item in dirlist
                return Q.nfcall(fs.stat, path.join(startPath, item))
                    .then(function(stat) {
                        //check if item is a directory
                        if (stat.isDirectory()) {
                            //recursive!! find files in subdirectory
                            return findFiles(path.join(startPath, item), filter, files)
                                .catch(function(error){
                                    console.log("could not read path: " + error.toString());
                                })
                                .finally(function() {
                                    //resolve async job after promise of subprocess of finding files has been resolved
                                    return done();
                                 });
                        //check if item is a file, that matches the filter and add it to files array
                        } else if (item.indexOf(filter) >= 0) {
                            files.push(path.join(startPath, item));
                            return done();
                        //file is no directory and does not match the filefilter -> don't do anything
                        } else {
                            return done();
                        }
                    })
                    .catch(function(error){
                        ideferred.reject("Could not stat: " + error.toString());
                    });
            }, function() {
                return ideferred.resolve(); //async each has finished, so resolve inner deferred
            });
            return ideferred.promise;
        }).then(function() {
            //here you could do anything with the files of this recursion step (otherwise you would only need ONE deferred)
            return deferred.resolve(files); //resolve main deferred
        }).catch(function(error) {
            deferred.reject("Could not read dir: " + error.toString());
            return
        });
        return deferred.promise;
    }
    
    
    findFiles(process.env.START, process.env.FILTER, [])
        .then(function(files){
            console.log(files);
        })
        .catch(function(error){
            console.log("Problem finding files: " + error);
    })
    
    0 讨论(0)
  • 2020-12-08 00:26

    Old post but ES6 now handles this out of the box with the includes method.

    let files = ['file.json', 'other.js'];
    
    let jsonFiles = files.filter(file => file.includes('.json'));
    
    console.log("Files: ", jsonFiles) ==> //file.json
    
    0 讨论(0)
提交回复
热议问题