नोड्ज में एक फ़ोल्डर के तहत, * .html विस्तार द्वारा फ़ाइलें खोजें


92

मैं सभी * .html फाइलों को src फोल्डर और उसके सभी उप फोल्डर में नोडज का उपयोग करके खोजना चाहता हूं। यह करने के लिए सबसे अच्छा तरीका क्या है?

var folder = '/project1/src';
var extension = 'html';
var cb = function(err, results) {
   // results is an array of the files with path relative to the folder
   console.log(results);

}
// This function is what I am looking for. It has to recursively traverse all sub folders. 
findFiles(folder, extension, cb);

मुझे लगता है कि बहुत सारे डेवलपर्स के पास महान और परीक्षण किया हुआ समाधान होना चाहिए और इसका उपयोग खुद लिखने से बेहतर है।


यदि आप regex द्वारा फ़ाइलों को खोजना चाहते हैं, तो फ़ाइल-रेगेक्स लाइब्रेरी का उपयोग करें , जो समवर्ती फ़ाइल खोज को समवर्ती रूप से करता है।
आकाश बाबू

जवाबों:


92

नोड .js, पुनरावर्ती सरल कार्य:

var path = require('path'), fs=require('fs');

function fromDir(startPath,filter){

    //console.log('Starting from dir '+startPath+'/');

    if (!fs.existsSync(startPath)){
        console.log("no dir ",startPath);
        return;
    }

    var files=fs.readdirSync(startPath);
    for(var i=0;i<files.length;i++){
        var filename=path.join(startPath,files[i]);
        var stat = fs.lstatSync(filename);
        if (stat.isDirectory()){
            fromDir(filename,filter); //recurse
        }
        else if (filename.indexOf(filter)>=0) {
            console.log('-- found: ',filename);
        };
    };
};

fromDir('../LiteScript','.html');

RegExp जोड़ें यदि आप फैंसी प्राप्त करना चाहते हैं, और इसे सामान्य बनाने के लिए कॉलबैक करें।

var path = require('path'), fs=require('fs');

function fromDir(startPath,filter,callback){

    //console.log('Starting from dir '+startPath+'/');

    if (!fs.existsSync(startPath)){
        console.log("no dir ",startPath);
        return;
    }

    var files=fs.readdirSync(startPath);
    for(var i=0;i<files.length;i++){
        var filename=path.join(startPath,files[i]);
        var stat = fs.lstatSync(filename);
        if (stat.isDirectory()){
            fromDir(filename,filter,callback); //recurse
        }
        else if (filter.test(filename)) callback(filename);
    };
};

fromDir('../LiteScript',/\.html$/,function(filename){
    console.log('-- found: ',filename);
});

डेमो कोड के लिए बहुत बहुत धन्यवाद! मैंने आपके कोड के शीर्ष पर कुछ जोड़ा है और यह बहुत अच्छा काम करता है! मैंने आपके लाइटस्क्रिप्ट प्रोजेक्ट को भी जांचा, और यह आश्चर्यजनक है। मैंने इसे गितुब पर अभिनय किया है!
निकोलस S.Xu

विस्तार के बिना फाइलनाम खोजने के लिए अच्छी छोटी स्क्रिप्ट - मेरे मामले में मेरे पास कुछ Jpegs थे और यह जानने की आवश्यकता थी कि क्या एक अलग डायर में मूल फ़ाइल png या jpeg थी, इससे मदद मिलती है
रिकी ओडिन मैथ्यू

80

मुझे ग्लोब पैकेज का उपयोग करना पसंद है :

const glob = require('glob');

glob(__dirname + '/**/*.html', {}, (err, files)=>{
  console.log(files)
})

1
आम तौर पर साधारण चीजों के लिए पैकेज का प्रशंसक नहीं है, लेकिन ग्लोब के नोड नोड कार्यान्वयन में निर्मित होने से पहले यह केवल समय की बात है। यह फ़ाइल चयन का regexp बनने की तरह है।
सिपाही रीड

27

क्या, पर लटका ?! ... ठीक है हाँ, शायद यह किसी और को भी समझ में आता है।

[ आप को 7 मन पसंद]

fs = import('fs');
let dirCont = fs.readdirSync( dir );
let files = dirCont.filter( function( elm ) {return elm.match(/.*\.(htm?html)/ig);});

Regex के साथ जो कुछ भी करें उसे फ़ंक्शन में डिफ़ॉल्ट रूप से सेट किए गए एक तर्क दें।


2
यह केवल रूट डायरेक्टरी में मैचिंग फाइल प्राप्त करेगा।
स्वप्नकुमार

6
मैंने संपादित करने की कोशिश की और अस्वीकार कर दिया गया, जिससे मैं असहमत हूं। यहाँ मेरा प्रस्ताव है: stackoverflow.com/review/suggested-edits/19188733 wl जो भी समझ में आता है। इसके अलावा एफएस के लिए आयात गायब है। आपको जिन तीन पंक्तियों की आवश्यकता है, वे हैं: 1. const fs = require('fs');2. const dirCont = fs.readdirSync( dir );3. 3.const files = dirCont.filter( ( elm ) => /.*\.(htm?html)/gi.test(elm) );
अवींद्र गोलचरण

सही क्षमा करें wl.fs वह जगह है जहाँ मैंने आयात के माध्यम से fs lib संग्रहीत किया है।
मास्टर जेम्स

ओह आयात शायद मेरा अपना कस्टम फंक्शन है जो अब के लिए आवश्यकता की ओर इशारा करता है इसलिए सुनिश्चित उपयोग की आवश्यकता है या आपको जो भी करना है।
मास्टर जेम्स

13

लुसियो के कोड के आधार पर, मैंने एक मॉड्यूल बनाया। यह एक के तहत विशिष्ट एक्सटेंशन वाली सभी फाइलों के साथ वापस आ जाएगा। बस इसे यहाँ पोस्ट करें अगर किसी को इसकी आवश्यकता हो।

var path = require('path'), 
    fs   = require('fs');


/**
 * Find all files recursively in specific folder with specific extension, e.g:
 * findFilesInDir('./project/src', '.html') ==> ['./project/src/a.html','./project/src/build/index.html']
 * @param  {String} startPath    Path relative to this file or other file which requires this files
 * @param  {String} filter       Extension name, e.g: '.html'
 * @return {Array}               Result files with path string in an array
 */
function findFilesInDir(startPath,filter){

    var results = [];

    if (!fs.existsSync(startPath)){
        console.log("no dir ",startPath);
        return;
    }

    var files=fs.readdirSync(startPath);
    for(var i=0;i<files.length;i++){
        var filename=path.join(startPath,files[i]);
        var stat = fs.lstatSync(filename);
        if (stat.isDirectory()){
            results = results.concat(findFilesInDir(filename,filter)); //recurse
        }
        else if (filename.indexOf(filter)>=0) {
            console.log('-- found: ',filename);
            results.push(filename);
        }
    }
    return results;
}

module.exports = findFilesInDir;

12

आप ऐसा करने के लिए Filehound का उपयोग कर सकते हैं ।

उदाहरण के लिए: सभी। Html फ़ाइलों को / tmp में खोजें:

const Filehound = require('filehound');

Filehound.create()
  .ext('html')
  .paths("/tmp")
  .find((err, htmlFiles) => {
    if (err) return console.error("handle err", err);

    console.log(htmlFiles);
});

अधिक जानकारी (और उदाहरणों) के लिए डॉक्स देखें: https://github.com/nspragg/filehound

डिस्क्लेमर : मैं लेखक हूं।


8

मैंने उपरोक्त उत्तरों को देखा है और इस संस्करण को एक साथ मिलाया है जो मेरे लिए काम करता है:

function getFilesFromPath(path, extension) {
    let files = fs.readdirSync( path );
    return files.filter( file => file.match(new RegExp(`.*\.(${extension})`, 'ig')));
}

console.log(getFilesFromPath("./testdata", ".txt"));

यह परीक्षण पथ में फ़ोल्डर में पाई गई फ़ाइलों से फ़ाइल नाम का एक सरणी लौटाएगा ./testdata। नोड संस्करण 8.11.3 पर काम कर रहा है।


1
मैं RegExp के अंत में $ जोड़ूंगा:.*\.(${extension})$
Eugene

3

इसके लिए आप ओएस की मदद का इस्तेमाल कर सकते हैं। यहाँ एक क्रॉस-प्लेटफॉर्म समाधान है:

1. बेलो फंक्शन उपयोग करता है lsऔर dirपुनरावर्ती खोज नहीं करता है, लेकिन इसके सापेक्ष पथ हैं

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. bellow फ़ंक्शन का उपयोग करता है findऔर dir, पुनरावर्ती खोज करता है , लेकिन खिड़कियों पर इसके पूर्ण पथ हैं

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);
})

1
मैंने कभी नहीं सोचा था कि यह इस तरह से किया जा सकता है, क्योंकि मैं आवश्यकता ('child_process') के साथ पारिवारिक नहीं हूं, लेकिन यह बहुत अच्छा लग रहा है और मुझमें बहुत सारे विचारों को प्रेरित करता है। धन्यवाद!
निकोलस S.Xu

2
यह "नोड्ज का उपयोग" करने का तरीका नहीं है। यह OS का उपयोग कर रहा है, एक और प्रक्रिया शुरू कर रहा है, आदि। यह भी विफल रहता है अगर वहाँ ".html" में समाप्त हो रहा है, जैसे: files.html /
Lucio M. Tato

@ LucioM.Tato आप खोज करते समय फ़ाइल प्रकार निर्दिष्ट करते हैं। किसी समस्या के बहुत सारे समाधान हैं, अगर कोई आपके विचार से मेल नहीं खाता है तो इसका मतलब यह नहीं है कि यह गलत है, यह सिर्फ अलग है। यह उत्तर साबित करता है कि आप मौजूदा समाधानों का पुन: उपयोग कर सकते हैं चाहे कोई भी स्क्रिप्टिंग भाषा का उपयोग किया जाए।
एमिल कॉन्ड्रिया

बेशक, यह एक निर्देशिका पर पुनरावृत्ति और कुछ एक्सटेंशन के साथ फ़ाइलों को खोजने में कुछ भी गलत नहीं है, लेकिन मैं सिर्फ ओएस से यह सब जानकारी प्राप्त करना चाहता था क्योंकि मुझे पता था कि वह यह कर सकता है। :)
एमिल कॉन्ड्रिया

@EmilCondrea, IHMO यह "नोड का उपयोग करना" नहीं है जैसा कि ओपी ने पूछा था। वैसे भी अगर मैं आपको परेशान कर रहा हूं तो मैं नीचे को हटा दूंगा।
लुसियो एम। टेटो

3

निम्न कोड अंदर एक पुनरावर्ती खोज करता है। / (इसे उचित रूप से बदलें) और .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);

2

फ़ाइल- regex पर एक नज़र डालें

let findFiles = require('file-regex')
let pattern = '\.js'

findFiles(__dirname, pattern, (err, files) => {  
   console.log(files);
})

यह ऊपर स्निपेट jsवर्तमान निर्देशिका की सभी फाइलों को प्रिंट करेगा ।


यह वास्तव में सबसे आसान समाधान है।
kyeno

2

प्रतिष्ठा के कारण टिप्पणी नहीं जोड़ सकते, लेकिन निम्नलिखित पर ध्यान दें:

500,000 फ़ाइलों के एक फ़ोल्डर में फ़ाइलों का वाइल्डकार्ड सेट खोजने के लिए fs.readdir या नोड-ग्लोब का उपयोग करके ~ 2s लिया गया। DIR के साथ निष्पादन का उपयोग करके ~ 0.05s (गैर पुनरावर्ती) या ~ 0.45s (पुनरावर्ती) लिया गया। (मैं एक ही निर्देशिका में अपने पैटर्न से मेल खाती ~ 14 फ़ाइलों की तलाश कर रहा था)।

अब तक, मैं किसी भी नोडज कार्यान्वयन को खोजने में विफल रहा है जो दक्षता के लिए निम्न स्तर के ओएस वाइल्डकार्ड का उपयोग करता है। लेकिन उपरोक्त डीआईआर / एलएस आधारित कोड दक्षता के मामले में खिड़कियों में शानदार काम करता है। हालाँकि, linux बड़ी निर्देशिकाओं के लिए बहुत धीमा होगा


दिलचस्प है, वास्तव में।

नोट मुझे लगता है कि नवीनतम नोडज एफएस मॉड्यूल (12.13+? पुनरावृत्त निर्देशिका fns) में नए कार्य हैं। मैंने अभी तक उनकी कोशिश नहीं की है क्योंकि मैं 6.9.11 पर अटका हुआ हूं; यह देखना दिलचस्प होगा कि क्या वे इसके लिए कोई नई उपयोगी सुविधा प्रदान करते हैं। अब मेरी पोस्ट के बारे में सोच; ओएस कैशिंग पर भी विचार किया जाना चाहिए। मेरे 0.05s की संभावना होती है जब इसे कई बार चलाने के बाद मापा जाता है। मुझे आश्चर्य है कि FIRST 'DIR' की गति क्या है?
साइमन एच।

1

मेरे दो पेंस, फॉर-लूप के स्थान पर मैप का उपयोग कर रहे हैं

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

मैंने अभी देखा, आप समन्वयन एफएस विधियों का उपयोग कर रहे हैं, जो आपको आवेदन को अवरुद्ध कर सकते हैं, यहां एक वादा है कि एएसक्यू और क्यू का उपयोग करके async तरीका है , आप इसे START = / myfolder FILTER = "के साथ निष्पादित कर सकते हैं। jpg" नोड myfile .js यह मानते हुए कि आपने 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);
})

4
कॉलबैक नरक का एक बड़ा उदाहरण! :)
अफशीन मौजमी

2
आप सही हैं, इसे इस तरह दोबारा नहीं करेंगे: D हो सकता है कि मैं अगले दिन समय पाऊं, इसे सुलझाने के लिए async / इंतजार के साथ अंतर दिखाना होगा।
क्रिस्टोफ़ जोहान्सड्टर

0

इंस्टॉल

आप इस पैकेज को वॉक-सिंक द्वारा इंस्टॉल कर सकते हैं

yarn add walk-sync

प्रयोग

const walkSync = require("walk-sync");
const paths = walkSync("./project1/src", {globs: ["**/*.html"]});
console.log(paths);   //all html file path array

-2

पुरानी पोस्ट लेकिन ES6 अब इस बॉक्स को includesविधि से संभालती है ।

let files = ['file.json', 'other.js'];

let jsonFiles = files.filter(file => file.includes('.json'));

console.log("Files: ", jsonFiles) ==> //file.json

file.readdirSyncइसे बढ़ाने के लिए जा रहा हूं क्योंकि मैं उपयोग कर रहा था और एक्सटेंशन द्वारा फ़ाइलों को फ़िल्टर करने का एक सरल तरीका आवश्यक था । मुझे लगता है कि इस प्रश्न का उत्तर इस धागे में है लेकिन शायद सब कुछ नहीं है। फिर भी विचार करने लायक।
justinpage
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.