Я хотел бы найти все файлы * .html в папке src и всех ее подпапках с помощью nodejs. Как лучше всего это сделать?
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);
Я думаю, что у многих разработчиков должно быть отличное и проверенное решение, и лучше использовать его, чем писать самому.
node.js
find
file-extension
Николя С.Сю
источник
источник
Ответы:
node.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); });
источник
мне нравится использовать пакет glob :
const glob = require('glob'); glob(__dirname + '/**/*.html', {}, (err, files)=>{ console.log(files) })
источник
Что, подожди ?! ... Ладно, может быть, для кого-то это тоже имеет больше смысла.
[ nodejs 7, обратите внимание]
fs = import('fs'); let dirCont = fs.readdirSync( dir ); let files = dirCont.filter( function( elm ) {return elm.match(/.*\.(htm?html)/ig);});
Делайте все, что с регулярным выражением, сделайте его аргументом, который вы установили в функции со значением по умолчанию и т. Д.
источник
wl
вообще имеет смысл. Также отсутствует импорт для fs. Вам понадобятся три строчки: 1.const fs = require('fs');
2.const dirCont = fs.readdirSync( dir );
3.const files = dirCont.filter( ( elm ) => /.*\.(htm?html)/gi.test(elm) );
На основе кода Люцио я сделал модуль. Он вернет все файлы с определенными расширениями под одним. Просто разместите его здесь, если кому-нибудь это понадобится.
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;
источник
Для этого вы можете использовать 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
Отказ от ответственности : я автор.
источник
Я просмотрел приведенные выше ответы и смешал эту версию, которая мне подходит:
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.источник
.*\.(${extension})$
Для этого вы можете использовать справку ОС. Вот кроссплатформенное решение:
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. Приведенная ниже функция использует
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); })
источник
Следующий код выполняет рекурсивный поиск внутри ./ (измените его соответствующим образом) и возвращает массив абсолютных имен файлов, заканчивающихся на .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);
источник
Не могу добавить комментарий из-за репутации, но обратите внимание на следующее:
Использование fs.readdir или node-glob для поиска подстановочного набора файлов в папке из 500 000 файлов заняло ~ 2 секунды. Использование exec с DIR заняло ~ 0,05 с (нерекурсивный) или ~ 0,45 с (рекурсивный). (Я искал ~ 14 файлов, соответствующих моему шаблону в одном каталоге).
Пока мне не удалось найти какую-либо реализацию nodejs, которая использует поиск подстановочных знаков ОС низкого уровня для повышения эффективности. Но приведенный выше код на основе DIR / ls прекрасно работает в Windows с точки зрения эффективности. linux find, однако, скорее всего, будет очень медленным для больших каталогов.
источник
мои два пенса, используя карту вместо цикла
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);
источник
Взгляните на file-regex
let findFiles = require('file-regex') let pattern = '\.js' findFiles(__dirname, pattern, (err, files) => { console.log(files); })
Этот фрагмент выше распечатает все
js
файлы в текущем каталоге.источник
Я только что заметил, что вы используете методы sync fs, которые могут заблокировать ваше приложение, вот асинхронный способ на основе обещаний с использованием async и q , вы можете выполнить его с помощью START = / myfolder FILTER = ". Jpg" node 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); })
источник
Установить
вы можете установить этот пакет Walk-Sync с помощью
Применение
const walkSync = require("walk-sync"); const paths = walkSync("./project1/src", {globs: ["**/*.html"]}); console.log(paths); //all html file path array
источник
Старый пост, но ES6 теперь справляется с этим из коробки с помощью
includes
метода.let files = ['file.json', 'other.js']; let jsonFiles = files.filter(file => file.includes('.json')); console.log("Files: ", jsonFiles) ==> //file.json
источник
file.readdirSync
и нуждался в простом способе фильтрации файлов по расширению. Я думаю, что это отвечает на часть вопроса в этой ветке, но, возможно, не на все. Тем не менее стоит задуматься.