stdin - 雷博尔 3 : reading STDIN efficiently line by line (to make awk like tool)

标签 stdin rebol rebol3

我正在尝试制作一个类似 awk 的工具,它使用 Rebol 3 通过 bash 管道和工具处理更大的文本文件。我在 Rebol 3 中逐行读取 STDIN 时遇到问题?

例如,此 shell 命令生成 3 行:

$ (echo "first line" ; echo "second line" ; echo "third line" )
first line
second line
third line

但是 Rebol 的输入字会同时读取所有 3 行。我希望它会在换行符处停止,因为如果您交互使用输入,它就会停止。

r3 --do 'while [ x: input ] [ if empty? x [ break ] print x print   "***" ]' 
abcdef
abcdef
***
blabla
blabla
***

但是当我一起运行它时,它会立即读取整个输入。我可以一次读取所有内容并分成几行,但我希望它以“流式”方式工作,因为我通常cat许多1000行。

$ (echo "first line" ; echo "second line" ; echo "third line" )  \
  | r3 --do 'while [ x: input ] [ if empty? x [ break ] print x print "***" ]' 
first linesecond linethird line
***

我还查看了输入的来源来实现类似的功能。我可以在 while 循环中逐个字符地读取字符并检查换行符,但这似乎效率不高。

最佳答案

我想通了,即使在 10000 行的大文件上,它似乎也能很好地工作。不过,它还可以写得更优雅和改进。

函数r3awk采用STDIN和每行执行的代码块,并将行变量绑定(bind)到它:

r3awk: func [ code /local a lines line partial ] [ 
    partial: copy ""
    lines: read/lines/string system/ports/input
    while [ not empty? lines ] [
        lines/1: rejoin [ partial lines/1 ]
        partial: pull lines
        foreach line lines [
            do bind code 'line
        ] 
        if error? try [ lines: read/lines/string system/ports/input ] [ lines: copy [] ]
    ]
    line: partial
    do bind code 'line
]    

它的工作原理是这样的。 read/lines 从流中读取多个字符并返回一个行 block 。每次调用它时,它都会像这样读取下一批字符,因此所有内容都包含在 while 循环中。代码作为 while 循环(而不是在最后)处理(执行代码块)。

这批字符不会以换行符结束,因此最后一行每次都是部分。下一批中的第一行也是如此,因此它将它们连接在一起。最后它必须处理最后一行(这次是非部分行)。 Try是因为某些行导致utf编码错误。

它可以在命令行中这样使用:

(echo "first line" ; echo "second line" ; echo "third line" ) | \
 r3 --import utils.r --do 'r3awk [ parse line [ copy x to space (print x) ] ]'
first
second
third

需要改进的地方:使功能总体上更好,删除重复的一些代码。检查如果读取/行确实在换行符处结束会发生什么。

关于stdin - 雷博尔 3 : reading STDIN efficiently line by line (to make awk like tool),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41889113/

相关文章:

html - 使用 REBOL 在文件中查找/替换跨行的字符串

rebol - 如何在 Rebol 2 中将变量的内容写入文本文件?

console - 如何清除 Rebol 控制台?

reflection - 为什么 Rebol 3 不尊重括号中的引用函数参数?

templates - Rebol 中的 'reword' 函数是什么,如何使用它?

c - 将行存储到动态结构中

c - 从 stdin、C 读取未知行数

stdin - 是否可以在阻塞模式下运行 sbatch?

filenames - 在 Rebol 3 GUI 中请求文件的正确方法(Saphir 版本)

java - 从文件中获取 stdin 来控制后台 java 进程