এক্সটেনশন দ্বারা ফাইলগুলি সন্ধান করুন, * .html নোডেজের একটি ফোল্ডারের নীচে


92

আমি এসসিআর ফোল্ডারে সমস্ত * .html ফাইল এবং নোডেজ ব্যবহার করে এর সমস্ত সাব ফোল্ডার সন্ধান করতে চাই। এটা করার সবচেয়ে ভালো উপায় কি?

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

আমি মনে করি অনেক বিকাশকারীদের দুর্দান্ত এবং পরীক্ষিত সমাধান হওয়া উচিত এবং এটি নিজের লেখার চেয়ে এটি ব্যবহার করা ভাল।


আপনি যদি রেজেক্সের মাধ্যমে ফাইলগুলি অনুসন্ধান করতে চান, তবে ফাইল-রেজেক্স লাইব্রেরি ব্যবহার করুন , যা একই সাথে পুনরাবৃত্ত ফাইল অনুসন্ধান করে।
আকাশ বাবু

উত্তর:


92

নোড.জেএস, পুনরাবৃত্তি সহজ ফাংশন:

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

ডেমো কোডের জন্য অনেক ধন্যবাদ! আমি আপনার কোডের উপরে কিছু যুক্ত করেছি এবং এটি দুর্দান্ত কাজ করে! আমি আপনার লাইটস্ক্রিপ্ট প্রকল্পও পরীক্ষা করে দেখেছি এবং এটি আশ্চর্যজনক। আমি এটি গিথুবে অভিনয় করেছি!
নিকোলাস এস এক্সু

এক্সটেনশন ছাড়াই ফাইলের নামগুলি সন্ধানের জন্য খুব ছোট স্ক্রিপ্ট - আমার ক্ষেত্রে আমার কিছু জেপিগ ছিল এবং এটির অন্য ডিয়ারের মূল ফাইলটি পিএনজি বা জেপিগ ছিল কিনা তা খুঁজে পাওয়ার দরকার ছিল
রিকি ওডিন ম্যাথিউজ

80

আমি গ্লোব প্যাকেজ ব্যবহার করতে পছন্দ করি :

const glob = require('glob');

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

4
সাধারণত সাধারণ জিনিসগুলির জন্য প্যাকেজগুলির অনুরাগী নন, তবে গ্লোব নোড জেএস বাস্তবায়নের আগে এটি কেবল সময়ের বিষয়। এটি ফাইল নির্বাচনের পুনর্নির্মাণের ধরণ।
সেফ রিড

27

কি, স্তব্ধ ?! ... ঠিক আছে, সম্ভবত এটি অন্য কারও কাছেও আরও বোঝা যায়।

[মনে রাখবেন 7 মনে রাখবেন]

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

রেগেক্সের সাথে যা কিছু করুন তা ডিফল্ট ইত্যাদির সাহায্যে ফাংশনে আপনি যে যুক্তিটি সেট করেছেন তা করুন Do


4
এটি কেবল রুট ডিরেক্টরিতে মিলবে ফাইলগুলি।
স্বপ্নেরকুমার

6
আমি সম্পাদনা করার চেষ্টা করেছি এবং প্রত্যাখ্যাত হয়েছিল, যার সাথে আমি একমত নই। আমার প্রস্তাবটি এখানে: stackoverflow.com/review/suggested-edits/19188733 যা wl কিছু বুঝায় sense এছাড়াও fs এর জন্য আমদানি অনুপস্থিত। আপনার যে তিনটি লাইনের প্রয়োজন তা const fs = require('fs');const dirCont = fs.readdirSync( dir );const files = dirCont.filter( ( elm ) => /.*\.(htm?html)/gi.test(elm) );
হ'ল

ডান আফসোস ডাব্লুএল.এফএস যেখানে আমি আমদানির মাধ্যমে 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

এটি করতে আপনি ফাইলহাউন্ড ব্যবহার করতে পারেন ।

উদাহরণস্বরূপ: / tmp এ সমস্ত html ফাইল সন্ধান করুন:

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 এ কাজ করা।


4
আমি RegExp এর শেষে $ যুক্ত করতাম:.*\.(${extension})$
ইউজিন

3

আপনি এটির জন্য ওএস সহায়তা ব্যবহার করতে পারেন। এখানে একটি ক্রস প্ল্যাটফর্ম সমাধান:

1. নিচের ফাংশন ব্যবহার lsএবং dirএবং যাও recursively অনুসন্ধান নেই কিন্তু এটি আপেক্ষিক পাথ হয়েছে

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. নিচের ফাংশন ব্যবহার findএবং dir, অনুসন্ধান যাও recursively কিন্তু Windows তে এটি পরম পাথ হয়েছে

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

4
আমি কখনও ভাবিনি যে এটি এটি করা যেতে পারে, যেহেতু আমি প্রয়োজনীয় ('চাইল্ড_প্রসেস') নিয়ে পারিবারিক নই। তবে এটি দেখতে খুব ভাল লাগে এবং আমার মধ্যে অনেক চিন্তাভাবনা অনুপ্রেরণা জাগায়। ধন্যবাদ!
নিকোলাস এস এক্সু

4
এটি "নোডেজ ব্যবহার করে" করার উপায় নয়। এটি ওএস ব্যবহার করছে, অন্য প্রক্রিয়া শুরু করছে, ইত্যাদি It ".html" এর সমাপ্তির কোনও ডায়ার থাকে তবে এটি ব্যর্থ হয়, উদাহরণস্বরূপ: ফাইলের এইচটিএমএল /
লুসিও এম

@ লুসিওএম.তাতো আপনি অনুসন্ধানের সময় ফাইলের ধরণ উল্লেখ করুন। একটি সমস্যার অনেকগুলি সমাধান রয়েছে, যদি কেউ আপনার ধারণার সাথে মেলে না তবে এটির অর্থ এটি ভুল নয়, এটি অন্যরকম। এই উত্তরটি প্রমাণ করে যে কোনও স্ক্রিপ্টিং ভাষা ব্যবহার করা হোক না কেন আপনি বিদ্যমান সমাধানগুলি পুনরায় ব্যবহার করতে পারেন।
এমিল কনড্রেয়া

অবশ্যই এটি কোনও ডিরেক্টরিতে পুনরাবৃত্তি হওয়া এবং নির্দিষ্ট এক্সটেনশানযুক্ত ফাইলগুলি সন্ধানের ক্ষেত্রে কোনও ভুল নয় তবে আমি কেবল ওএসের কাছ থেকে এই সমস্ত তথ্য গ্রহণ করতে চেয়েছিলাম কারণ আমি জানতাম যে সে এটি করতে পারে। :)
এমিল কনড্রেয়া

@ এমিলকন্ড্রিয়া, আইএইচএমও এটি ওপি যেমনটি বলেছে তেমন "নোড ব্যবহার করছে না"। যাইহোক আমি ডাউনভোটটি সরিয়ে ফেলব যদি তা আপনাকে বিরক্ত করে।
লুসিও এম টাটো

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বর্তমান ডিরেক্টরিতে সমস্ত ফাইল মুদ্রণ করবে ।


এটি আসলেই সবচেয়ে সহজ সমাধান out
কায়ানো 13

2

খ্যাতির কারণে কোনও মন্তব্য যুক্ত করতে পারেন না, তবে নিম্নলিখিতটি লক্ষ্য করুন:

500,000 ফাইলের ফোল্ডারে ফাইলের একটি ওয়াইল্ডকার্ড সেট খুঁজে পেতে fs.readdir বা নোড-গ্লোব ব্যবহার করে ~ 2s নিয়েছে। ডিআইআর এর সাথে এক্সিকিউটিভ ব্যবহার করতে ~ 0.05s (পুনঃব্যবসায়ী) বা .4 0.45s (পুনরাবৃত্ত) লাগে। (আমি একক ডিরেক্টরিতে আমার প্যাটার্নের সাথে মিলিয়ে 14 ডলার ফাইল সন্ধান করছি)।

এখনও অবধি, আমি কোনও নোডেজ বাস্তবায়ন খুঁজে পেতে ব্যর্থ হয়েছি যা দক্ষতার জন্য অনুসন্ধানের জন্য নিম্ন স্তরের ওএস ওয়াইল্ডকার্ড ব্যবহার করে। তবে উপরের ডিআইআর / এলএস ভিত্তিক কোড দক্ষতার দিক থেকে উইন্ডোজগুলিতে দুর্দান্তভাবে কাজ করে। লিনাক্স সন্ধান, তবে বৃহত্তর ডিরেক্টরিগুলির জন্য সম্ভবত খুব ধীর হবে


সত্যই, আকর্ষণীয়।
ফিলিপ

দ্রষ্টব্য আমি দেখতে পাচ্ছি সর্বশেষ নোডেজ এফএস মডিউলে নতুন ক্রিয়াকলাপ রয়েছে (12.13+? পুনরাবৃত্তি ডিরেক্টরি fns?)। আমি এখনও তাদের চেষ্টা করিনি কারণ আমি আপাতত 6.9.11 এ আটকেছি; তারা এটির জন্য কোনও নতুন দরকারী বৈশিষ্ট্য সরবরাহ করে কিনা তা আকর্ষণীয় হবে। আমার পোস্ট সম্পর্কে এখন চিন্তা; ওএস ক্যাচিংয়ের বিষয়টিও বিবেচনা করা উচিত। আমার 0.05 গুলি এটি বেশ কয়েকবার চালানোর পরে পরিমাপ করা হত। আমি ভাবছি প্রথম 'ডিআইআর' গতি কি?
সাইমন এইচ

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

আমি কেবল লক্ষ্য করেছি, আপনি সিঙ্ক এফএস পদ্ধতি ব্যবহার করছেন, এটি আপনার অ্যাপ্লিকেশনটিকে ব্লক করতে পারে, এখানে অ্যাসিঙ্ক এবং কিউ ব্যবহার করে প্রতিশ্রুতি ভিত্তিক অ্যাসিঙ্ক পদ্ধতি রয়েছে , আপনি এটি START = / মাইফোল্ডার ফিল্টার = "দিয়ে কার্যকর করতে পারেন। jpg" নোড মাইফাইল.জেএস, ধরে নিলে আপনি নীচের কোডটি 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
কলব্যাক নরকের একটি দুর্দান্ত উদাহরণ! :)
আফশিন মোয়াজামী

4
আপনি ঠিক বলেছেন, এইভাবে আর এটি করবেন না: ডি সম্ভবত আমি পরের দিনগুলি খুঁজে পাব, এটি অ্যাসিঙ্কের সাথে সমাধান করে / পার্থক্যটি দেখানোর জন্য অপেক্ষা করব।
ক্রিস্টোফ জোহানসডোটার


-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এক্সটেনশান দ্বারা ফাইলগুলি ফিল্টার আউট করার জন্য একটি সহজ উপায় এবং প্রয়োজন ছিল । আমি মনে করি এটি এই থ্রেডে প্রশ্নের অংশের উত্তর দেয় তবে সম্ভবত সব কিছুই না। এখনও বিবেচনা মূল্য।
জাস্টিনপেজ 21
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.