【问题标题】:How to read unbuffered input of lines ending with "\r" or "\n"?如何读取以“\r”或“\n”结尾的行的无缓冲输入?
【发布时间】:2018-12-20 19:48:35
【问题描述】:

我正在编写一个用于过滤的简单程序 来自管道的输入。大部分输入作为输出发送 原封不动。部分修改或用于提取 信息。以最简单的形式——什么都不做—— 程序filter是:

$|++;

while (<>) {
    print;
}

主程序有时会输出其进度更新 任务,通过使用覆盖相同的视觉内容 以回车符结尾的行。将此类内容传输到 filter 阻止所有输出:

$ perl -e '$|++; print ++$a, "\r" and sleep 1 while 1' | filter

有没有一种简单的方法可以在同一个循环中读取这些行 时尚,还是我应该走sysread 的方式?我在找 类似于如果有可能会发生的事情 将记录分隔符设置为“\n\r”。

【问题讨论】:

  • 您可以使用$/设置记录分隔符。只需在循环之前将其设置为“\r”即可。
  • @beasy 当然可以,但是以“\n”结尾的普通行将被缓冲到下一个“\r”,对吧?
  • 哦,你的意思是输入行有时以“\n”结尾,有时以“\r”结尾?
  • @beasy 是的。正如我所提到的,“程序有时会通过使用以回车符结尾的行来输出其任务的进度更新 […]”。我的单行示例仅输出 \r 行,只是为了演示这种技术,以防不清楚或不知道。

标签: perl io stdin


【解决方案1】:

如果输入不是那么大以至于担心效率,这个版本的filter 更健壮

while (!eof(STDIN)) {
    $_ .= getc(STDIN);
    if (/[\r\n]/) {
        # manipulate $_, if desired
        print;
        $_ = "";
    }
}
print;

【讨论】:

  • 谢谢,太好了。您在上面的 cmets 中链接的模块也非常出色。我很失望地阅读了文档中的 awk 注释,但现在没有了 :)
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2011-05-03
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多