Je voudrais trouver tous les fichiers * .html dans le dossier src et tous ses sous-dossiers en utilisant nodejs. Quelle est la meilleure façon de procéder?
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);
Je pense que beaucoup de développeurs devraient avoir une solution excellente et testée et il vaut mieux l'utiliser que d'en écrire une moi-même.
node.js
find
file-extension
Nicolas S.Xu
la source
la source
Réponses:
node.js, fonction simple récursive:
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');
ajoutez RegExp si vous voulez avoir de la fantaisie, et un rappel pour le rendre générique.
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); });
la source
j'aime utiliser le package glob :
const glob = require('glob'); glob(__dirname + '/**/*.html', {}, (err, files)=>{ console.log(files) })
la source
Quoi, accrochez-vous?! ... D'accord, peut-être que cela a plus de sens pour quelqu'un d'autre aussi.
[ nodejs 7 mind you]
fs = import('fs'); let dirCont = fs.readdirSync( dir ); let files = dirCont.filter( function( elm ) {return elm.match(/.*\.(htm?html)/ig);});
Faites ce que vous voulez avec regex en faire un argument que vous définissez dans la fonction avec une valeur par défaut, etc.
la source
wl
est si logique que ce soit. L'import pour fs est également manquant. Les trois lignes dont vous avez besoin sont: 1.const fs = require('fs');
2.const dirCont = fs.readdirSync( dir );
3.const files = dirCont.filter( ( elm ) => /.*\.(htm?html)/gi.test(elm) );
Sur la base du code de Lucio, j'ai créé un module. Il renverra un avec tous les fichiers avec des extensions spécifiques sous celui-ci. Postez-le ici au cas où quelqu'un en aurait besoin.
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;
la source
Vous pouvez utiliser Filehound pour ce faire.
Par exemple: recherchez tous les fichiers .html dans / 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); });
Pour plus d'informations (et des exemples), consultez la documentation: https://github.com/nspragg/filehound
Avertissement : je suis l'auteur.
la source
J'ai regardé les réponses ci-dessus et j'ai mélangé cette version qui fonctionne pour moi:
function getFilesFromPath(path, extension) { let files = fs.readdirSync( path ); return files.filter( file => file.match(new RegExp(`.*\.(${extension})`, 'ig'))); } console.log(getFilesFromPath("./testdata", ".txt"));
Ce test renverra un tableau de noms de fichiers à partir des fichiers trouvés dans le dossier au chemin
./testdata
. Travailler sur la version 8.11.3 du nœud.la source
.*\.(${extension})$
Vous pouvez utiliser l'aide du système d'exploitation pour cela. Voici une solution multiplateforme:
1. La fonction ci-dessous utilise
ls
etdir
et ne recherche pas récursivement mais elle a des chemins relatifsvar 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. La fonction ci-dessous utilise
find
etdir
, recherche récursivement mais sur Windows, elle a des chemins absolusvar 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); })
la source
Le code suivant effectue une recherche récursive dans ./ (modifiez-le de manière appropriée) et retourne un tableau de noms de fichiers absolus se terminant par .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);
la source
Impossible d'ajouter un commentaire en raison de la réputation, mais remarquez ce qui suit:
L'utilisation de fs.readdir ou node-glob pour trouver un ensemble de fichiers génériques dans un dossier de 500 000 fichiers a pris ~ 2s. L'utilisation de exec avec DIR a pris ~ 0,05 s (non récursif) ou ~ 0,45 s (récursif). (Je cherchais ~ 14 fichiers correspondant à mon modèle dans un seul répertoire).
Jusqu'à présent, je n'ai trouvé aucune implémentation de nodejs qui utilise des caractères génériques de bas niveau pour le système d'exploitation à la recherche d'efficacité. Mais le code basé sur DIR / ls ci-dessus fonctionne à merveille dans Windows en termes d'efficacité. linux find, cependant, sera probablement très lent pour les grands répertoires.
la source
mes deux pence, en utilisant la carte à la place de la boucle for
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);
la source
Jetez un œil à file-regex
let findFiles = require('file-regex') let pattern = '\.js' findFiles(__dirname, pattern, (err, files) => { console.log(files); })
Cet extrait de code ci-dessus afficherait tous les
js
fichiers du répertoire actuel.la source
Je viens de remarquer que vous utilisez des méthodes sync fs, qui pourraient bloquer votre application, voici une manière asynchrone basée sur la promesse utilisant async et q , vous pouvez l'exécuter avec START = / myfolder FILTER = ". Jpg" node myfile.js, en supposant que vous mettez le code suivant dans un fichier appelé 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); })
la source
Installer
vous pouvez installer ce package walk-sync en
Usage
const walkSync = require("walk-sync"); const paths = walkSync("./project1/src", {globs: ["**/*.html"]}); console.log(paths); //all html file path array
la source
Ancien poste, mais ES6 gère maintenant cela hors de la boîte avec la
includes
méthode.let files = ['file.json', 'other.js']; let jsonFiles = files.filter(file => file.includes('.json')); console.log("Files: ", jsonFiles) ==> //file.json
la source
file.readdirSync
et j'avais besoin d'un moyen simple de filtrer les fichiers par extension. Je pense que cela répond à une partie de la question de ce fil, mais peut-être pas à tout. Encore à considérer.