Saya ingin menemukan semua file * .html di folder src dan semua sub foldernya menggunakan nodejs. Apa cara terbaik untuk melakukannya?
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);
Saya pikir banyak pengembang harus memiliki solusi yang hebat dan teruji dan lebih baik menggunakannya daripada menulis sendiri.
node.js
find
file-extension
Nicolas S.Xu
sumber
sumber
Jawaban:
node.js, fungsi sederhana rekursif:
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');
tambahkan RegExp jika Anda ingin terlihat keren, dan panggil balik untuk membuatnya umum.
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); });
sumber
saya suka menggunakan paket glob :
const glob = require('glob'); glob(__dirname + '/**/*.html', {}, (err, files)=>{ console.log(files) })
sumber
Apa, tunggu ?! ... Oke ya, mungkin ini lebih masuk akal bagi orang lain juga.
[ nodejs 7 ingatlah]
fs = import('fs'); let dirCont = fs.readdirSync( dir ); let files = dirCont.filter( function( elm ) {return elm.match(/.*\.(htm?html)/ig);});
Lakukan apa pun dengan regex menjadikannya argumen yang Anda tetapkan dalam fungsi dengan default, dll.
sumber
wl
sangat masuk akal. Impor untuk fs juga hilang. Tiga baris yang Anda butuhkan adalah: 1.const fs = require('fs');
2.const dirCont = fs.readdirSync( dir );
3.const files = dirCont.filter( ( elm ) => /.*\.(htm?html)/gi.test(elm) );
Berdasarkan kode Lucio, saya membuat modul. Ini akan mengembalikan semua file dengan ekstensi tertentu di bawahnya. Cukup posting di sini jika ada yang membutuhkannya.
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;
sumber
Anda dapat menggunakan Filehound untuk melakukan ini.
Misalnya: temukan semua file .html di / 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); });
Untuk informasi lebih lanjut (dan contoh), lihat dokumen: https://github.com/nspragg/filehound
Penafian : Saya adalah penulisnya.
sumber
Saya telah melihat jawaban di atas dan telah menggabungkan versi ini yang bekerja untuk saya:
function getFilesFromPath(path, extension) { let files = fs.readdirSync( path ); return files.filter( file => file.match(new RegExp(`.*\.(${extension})`, 'ig'))); } console.log(getFilesFromPath("./testdata", ".txt"));
Tes ini akan mengembalikan larik nama file dari file yang ditemukan di folder di jalur
./testdata
. Bekerja pada node versi 8.11.3.sumber
.*\.(${extension})$
Anda dapat menggunakan bantuan OS untuk ini. Berikut adalah solusi lintas platform:
1. Fungsi di bawah ini menggunakan
ls
dandir
dan tidak mencari secara rekursif tetapi memiliki jalur relatifvar 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. Fungsi di bawah ini menggunakan
find
dandir
, mencari secara rekursif tetapi pada windows memiliki jalur absolutvar 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); })
sumber
Kode berikut melakukan pencarian rekursif di dalam ./ (mengubahnya dengan benar) dan mengembalikan larik nama file absolut yang diakhiri dengan .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);
sumber
Lihat file-regex
let findFiles = require('file-regex') let pattern = '\.js' findFiles(__dirname, pattern, (err, files) => { console.log(files); })
Potongan di atas akan mencetak semua
js
file di direktori saat ini.sumber
Tidak dapat menambahkan komentar karena reputasi, tetapi perhatikan hal berikut:
Menggunakan fs.readdir atau node-glob untuk menemukan sekumpulan file wildcard dalam folder berisi 500.000 file membutuhkan waktu ~ 2s. Menggunakan exec dengan DIR membutuhkan waktu ~ 0,05 detik (non rekursif) atau ~ 0,45 detik (rekursif). (Saya sedang mencari ~ 14 file yang cocok dengan pola saya dalam satu direktori).
Sejauh ini, saya gagal menemukan implementasi nodejs yang menggunakan wildcard OS tingkat rendah untuk mencari efisiensi. Tetapi kode berbasis DIR / ls di atas bekerja dengan sangat baik di windows dalam hal efisiensi. linux menemukan, bagaimanapun, kemungkinan akan sangat lambat untuk direktori besar.
sumber
dua pence saya, menggunakan peta sebagai pengganti 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);
sumber
Saya baru saja memperhatikan, Anda menggunakan metode sinkronisasi fs, yang mungkin memblokir aplikasi Anda, berikut adalah cara asinkron berbasis janji menggunakan async dan q , Anda dapat menjalankannya dengan START = / myfolder FILTER = ". Jpg" node myfile.js, dengan asumsi Anda meletakkan kode berikut dalam file bernama 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); })
sumber
Install
Anda dapat menginstal paket ini berjalan-sync oleh
Pemakaian
const walkSync = require("walk-sync"); const paths = walkSync("./project1/src", {globs: ["**/*.html"]}); console.log(paths); //all html file path array
sumber
Posting lama tetapi ES6 sekarang menangani ini di luar kotak dengan
includes
metode.let files = ['file.json', 'other.js']; let jsonFiles = files.filter(file => file.includes('.json')); console.log("Files: ", jsonFiles) ==> //file.json
sumber
file.readdirSync
dan membutuhkan cara sederhana untuk memfilter file dengan ekstensi. Saya pikir ini menjawab sebagian dari pertanyaan di utas ini, tetapi mungkin tidak semuanya. Masih layak dipertimbangkan.