I have a short script that I run at command line that searches a variable amount of files for a number and returns the first line number for each file it is found within.
How can I alter the output of the file to return a single text line of the results and write it to a file? As well as return the count of how many of the variable number of files had the number, to a second file?
Script
const readline = require("readline");
const fs = require("fs");
const SearchFiles = (readStream, filePath, queries) => {
let lineCount = 0;
let hold='';
let matches = new Map();
queries.forEach((query) => matches.set(query, []));
return new Promise((resolve, reject) => {
readStream.on("line", (line) => {
lineCount++;
for (let query of matches.keys()) {
if (searchForTerm(line, query))
{
matches.set(query, [...matches.get(query), lineCount]);
}}
});
readStream.on("close", () =>
resolve({
filePath,
matches,
})
);
});
};
const searchForTerm = (line, query) => line.match(query);
const createLineInterfaces = (filePaths) =>
filePaths.map((filePath) => {
const readStream = readline.createInterface({
input: fs.createReadStream(filePath),
});
return {
filePath,
readStream,
};
});
var lookup =56700;
var matchme =new RegExp("\\b" + lookup + "\\b");
const filesToSearch = ["/users/myname/desktop/mypath/threehundred_1191_37.txt", "/users/myname/desktop/mypath/threehundred_1191_37.txt", "/users/myname/desktop/mypath/threehundred_1191_36.txt", "/users/myname/desktop/mypath/threehundred_1191_35.txt", "/users/myname/desktop/mypath/threehundred_1191_38.txt", "/users/myname/desktop/mypath/threehundred_1191_39.txt", "/users/myname/desktop/mypath/threehundred_1191_40.txt", "/users/myname/desktop/mypath/threehundred_1191_41.txt"];
const queriesToSearch = [matchme];
let searchProms = createLineInterfaces(
filesToSearch
).map(({ readStream, filePath }) =>
SearchFiles(readStream, filePath, queriesToSearch)
);
Promise.all(searchProms).then((searchResults) =>
searchResults.forEach((result) => console.log(result))
)
Current Output
{
filePath: '/users/myname/desktop/mypath/threehundred_1191_37.txt',
matches: Map(1) { /\b56700\b/ => [ 52313 ] }
}
{
filePath: '/users/myname/desktop/mypath/threehundred_1191_36.txt',
matches: Map(1) { /\b56700\b/ => [ 52335 ] }
}
{
filePath: '/users/myname/desktop/mypath/threehundred_1191_35.txt',
matches: Map(1) { /\b56700\b/ => [] }
}
{
filePath: '/users/myname/desktop/mypath/threehundred_1191_38.txt',
matches: Map(1) { /\b56700\b/ => [ 52491 ] }
}
{
filePath: '/users/myname/desktop/mypath/threehundred_1191_39.txt',
matches: Map(1) { /\b56700\b/ => [ 52392 ] }
}
{
filePath: '/users/myname/desktop/mypath/threehundred_1191_40.txt',
matches: Map(1) { /\b56700\b/ => [ 52430 ] }
}
{
filePath: '/users/myname/desktop/mypath/threehundred_1191_41.txt',
matches: Map(1) { /\b56700\b/ => [ 52450 ] }
}
{
filePath: '/users/myname/desktop/mypath/threehundred_1191_42.txt',
matches: Map(1) { /\b56700\b/ => [ 52425 ] }
}
Wanted Output written to a First file
yes yes non yes yes yes yes yes
Wanted Output written to a Second file
7
The yes/non string is in order that the files were given to search in the array. Yes means it is in file, non means it was not found.
Note I pretty much focus on PHP and python --- I just started nodejs 5 days ago and attempted this on my own with async/wait but it was no where as fast as this script... most likely because I have not mastered the .then, and promise.all with array_map.
I am at crunch time so the script above is being reused from this post below: How do I write the Regex for a Node app that acts like a simple JS linter with a condition as well
I was able to solve this isssue, with better organization of the coding as well as some significant optimization gain.
THE NEW OPTIMIZED CODE
const fs = require('fs');
const readline = require('readline')
const task_id = 1;
let folder=1;
let subfolder=1;
let pastsearch=1;
const myarray=[6567,50105,67637,293697];
const mylen = myarray.length;
const myfiles=['file_1.txt','file_2.txt'];
fs.writeFile('/pathtomyfile/', '', function(){console.log('done')})
fs.writeFile('/pathtomyfile/', '', function(){console.log('done')})
const p1 = new Promise((resolve, reject) => {
let lineCount = 0;
let v=0;
let yesnon = "non";
let readStream = readline.createInterface({
input: fs.createReadStream('/pathtofile/round_'+task_id+'/threehundred_'+folder+'/'+subfolder+'/'+myfiles[0],'utf8')
});
readStream.on("line", (line) => {
lineCount++;
if(line==pastsearch)
{
yesnon="yes";
v++;
}
});
readStream.on('end', () => {
console.log('end');
readStream.destroy();
});
readStream.on("close", () =>
resolve({
yesnon
})
)
});
const p2 = new Promise((resolve, reject) => {
let readStream = readline.createInterface({
input: fs.createReadStream('/pathtofile/round_'+task_id+'/threehundred_'+folder+'/'+subfolder+'/'+myfiles[1],'utf8')
});
let lineCount = 0; let v=0;
let yesnon = "non";
readStream.on("line", (line) => {
lineCount++;
if(line==pastsearch)
{
yesnon="yes";
v++;
}
});
readStream.on('end', () => {
console.log('end');
readStream.destroy();
});
readStream.on("close", () =>
resolve({
yesnon
}) )
});
for(let h=0; h<3; h++)
{
folder++
subfolder++
pastsearch=myarray[h];
Promise.all([p1, p2]).then((results) => {
const output = results.map( ({yesnon}) => yesnon).join(' ');
fs.appendFileSync('/pathtofile/plain_round'+task_id+'.txt',output+"\n", 'utf8');
const output2 = results.map( ({yesnon}) => yesnon);
let count = 0;
function countValues(array, countItem) {
array.forEach(itm => {
if (itm == countItem) count++;
});
return count;
}
const myresult34=countValues(output2, "yes");
fs.appendFileSync('/pathtofile/round'+task_id+'.txt',myresult34+"\n", 'utf8');
});
}