Node.js代码运行时输出多余行问题修复求助
修复Node.js读取文本文件时多余输出行的问题
问题场景
执行命令node index.js test.txt '${1} ${2} ${3} ${4}'时,预期输出文件每行的前4个单词,但实际输出多了一行 ${2} ${3} ${4}。
原代码如下:
const fs = require('fs'); function processFile(filePath) { const content = fs.readFileSync(filePath, 'utf-8'); const lines = content.split('\n'); const wordIdMaps = lines.map(() => ({ wordIdMap: {}, currentId: 1 })); lines.forEach((line, index) => { const words = line.split(' '); const wordIdMap = wordIdMaps[index].wordIdMap; let currentId = wordIdMaps[index].currentId; words.forEach((word) => { if (!wordIdMap[word]) { wordIdMap[word] = currentId; currentId++; } }); }); return { lines, wordIdMaps }; // Return both lines and wordIdMaps } function customConsoleLog(logFormat, wordIdMaps) { const lines = wordIdMaps.map((map) => Object.entries(map.wordIdMap).map(([word, id]) => `${word}:${id}`).join(' ')); lines.forEach((line, index) => { const wordIdMap = wordIdMaps[index].wordIdMap; const replacedLog = logFormat.replace(/\${(\d+)}/g, (_, id) => { const word = Object.keys(wordIdMap).find((key) => wordIdMap[key] == id); return word !== undefined ? word : '${' + id + '}'; }); const words = line.split(' '); const replacedLine = replacedLog.replace(/\${\d+}/g, (match) => { const id = match.slice(2, -1); return words[id - 1] !== undefined ? words[id - 1] : match; }); console.log(replacedLine); }); } // Command-line arguments const filePath = process.argv[2]; const logFormat = process.argv[3]; if (!filePath || !logFormat) { console.log('Please provide both a file path and a custom console log format as command-line arguments.'); } else { const { lines, wordIdMaps } = processFile(filePath); customConsoleLog(logFormat, wordIdMaps); }
预期输出:
apple boy cat dog elephant fish god hen
实际输出:
apple boy cat dog elephant fish god hen ${2} ${3} ${4}
错误原因
问题出在processFile函数的content.split('\n'):当文本文件末尾存在换行符时,拆分后会生成一个空字符串元素。这个空行对应的wordIdMap是空对象,在customConsoleLog处理时,无法找到对应单词替换${1},导致${1}被替换为空,剩下 ${2} ${3} ${4}输出,形成多余行。
修复方案
步骤1:过滤空行
在processFile函数中,拆分行后过滤掉空行和纯空白行:
将
const lines = content.split('\n');
修改为
const lines = content.split('\n').filter(line => line.trim() !== '');
步骤2:优化customConsoleLog函数(可选)
原函数存在冗余的行生成逻辑,且两次替换属于重复操作,可简化为一次替换:
function customConsoleLog(logFormat, lines) { lines.forEach(line => { const words = line.split(' '); const replacedLine = logFormat.replace(/\${(\d+)}/g, (_, id) => { const idx = parseInt(id) - 1; return words[idx] !== undefined ? words[idx] : `\${${id}}`; }); console.log(replacedLine); }); }
调用时只需传入lines:
customConsoleLog(logFormat, lines);
修复后的完整代码
const fs = require('fs'); function processFile(filePath) { const content = fs.readFileSync(filePath, 'utf-8'); // 过滤空行和纯空白行 const lines = content.split('\n').filter(line => line.trim() !== ''); const wordIdMaps = lines.map(() => ({ wordIdMap: {}, currentId: 1 })); lines.forEach((line, index) => { const words = line.split(' '); const wordIdMap = wordIdMaps[index].wordIdMap; let currentId = wordIdMaps[index].currentId; words.forEach((word) => { if (!wordIdMap[word]) { wordIdMap[word] = currentId; currentId++; } }); }); return { lines, wordIdMaps }; } function customConsoleLog(logFormat, lines) { lines.forEach(line => { const words = line.split(' '); const replacedLine = logFormat.replace(/\${(\d+)}/g, (_, id) => { const idx = parseInt(id) - 1; return words[idx] !== undefined ? words[idx] : `\${${id}}`; }); console.log(replacedLine); }); } // Command-line arguments const filePath = process.argv[2]; const logFormat = process.argv[3]; if (!filePath || !logFormat) { console.log('Please provide both a file path and a custom console log format as command-line arguments.'); } else { const { lines } = processFile(filePath); customConsoleLog(logFormat, lines); }
验证效果
执行原命令后,输出将与预期一致,不会出现多余的空行及未替换的占位符。
内容的提问来源于stack exchange,提问作者coco bar
相关产品推荐
相关产品推荐

