如何在Deno的TextLineStream中避免末尾空行?
解决Deno TextLineStream输出末尾空行的问题
原因分析
你遇到的问题根源在于echo命令默认会在输出内容末尾自动添加一个换行符。你传入的参数是foo\n\nbar,实际stdout的输出内容是foo\n\nbar\n,TextLineStream会将每一个换行符作为行分隔符,最后那个末尾的换行就被解析成了一个空行。
解决方案1:修改echo命令禁止自动加换行
最简单的解决方式是给echo添加-n参数,这个参数会阻止echo在输出末尾添加额外的换行符:
import { TextLineStream } from "https://deno.land/std@0.136.0/streams/mod.ts"; const cmd1 = new Deno.Command("echo", {args:["-n", "foo\n\nbar"], stdout: "piped"}).spawn(); for await (const chunk of cmd1.stdout.pipeThrough(new TextDecoderStream).pipeThrough(new TextLineStream)) { console.log("result: ", chunk); }
运行这段代码后,输出会完全符合你的期望。
解决方案2:过滤流末尾的空行(适用于无法修改原命令的场景)
如果无法调整原命令的输出(比如输出来自其他不可控的程序),可以通过自定义转换流来过滤掉最后一个空行:
import { TextLineStream } from "https://deno.land/std@0.136.0/streams/mod.ts"; // 自定义转换流:过滤末尾的空行 const filterTrailingEmptyLine = new TransformStream<string, string>({ lines: [] as string[], transform(line, controller) { this.lines.push(line); }, flush(controller) { // 检查最后一行是否为空,若是则移除 if (this.lines.length > 0 && this.lines.at(-1) === "") { this.lines.pop(); } this.lines.forEach(line => controller.enqueue(line)); } }); const cmd1 = new Deno.Command("echo", {args:["foo\n\nbar"], stdout: "piped"}).spawn(); for await (const chunk of cmd1.stdout .pipeThrough(new TextDecoderStream) .pipeThrough(new TextLineStream) .pipeThrough(filterTrailingEmptyLine)) { console.log("result: ", chunk); }
这个方案会先收集所有行,在流结束时检查最后一行是否为空行,若是则移除后再输出所有行。
内容的提问来源于stack exchange,提问作者impactaky
相关产品推荐
相关产品推荐

