Asynchronous 过滤输出流以仅保留由特定行分隔的文本部分?

Asynchronous 过滤输出流以仅保留由特定行分隔的文本部分?,asynchronous,closures,lisp,common-lisp,sbcl,Asynchronous,Closures,Lisp,Common Lisp,Sbcl,我创建了一个简单的例子来说明我想要实现的目标。本质上,我需要运行一个shell命令并捕获它的输出,但只捕获它的特定部分。以下面的bash命令为例: >echo hello\nhello\nstart\nI\nWANT\n此\nTEXT\nend\nhello\n 你好 你好 开始 我 希望 这 文本 终止 你好 我期望的公共lisp输出将是我想要的文本列表。我有一个半工作的解决方案,但不知道如何才能获得确切的期望输出,以及是否有更惯用的方法来完成这项任务 首先,我创建一个闭包来跟踪我应该处理的线

我创建了一个简单的例子来说明我想要实现的目标。本质上,我需要运行一个shell命令并捕获它的输出,但只捕获它的特定部分。以下面的bash命令为例:

>echo hello\nhello\nstart\nI\nWANT\n此\nTEXT\nend\nhello\n 你好 你好 开始 我 希望 这 文本 终止 你好 我期望的公共lisp输出将是我想要的文本列表。我有一个半工作的解决方案,但不知道如何才能获得确切的期望输出,以及是否有更惯用的方法来完成这项任务

首先,我创建一个闭包来跟踪我应该处理的线:

defun-make预处理器 让proc行为零 兰姆达大街 康德 string=str start setf proc lines t string=str end setf proc lines nil 生产线 接下来,我使用let语句启动程序,然后在输出流中循环:

让*输入串联“字符串 你好\\n你好\\n开始\\n 我\\n想要\\n此\\n文本\\n 结束\\n您好\\n 命令串联“字符串回显\输入”\ *proc*uiop:启动程序命令:输出:流 流uiop:进程信息输出*proc* 听台词?制作预处理器 uiop:等待进程*proc* 边听边循环流收集 所有人都排队吗?读取行流 返回

我要这篇文章,我要 正如您所看到的,我不想要T和NIL值。我还必须使用uiop:wait过程,我并不特别喜欢这个过程,但我假设这是必需的

更广泛地说,我有大约100个这样的命令需要运行和解析。因此,我将同时运行此程序。这只是为了一些观点,我将在另一个问题中发布

> (loop for e in '(NIL NIL T "I" "WANT" "THIS" "TEXT" NIL NIL NIL)
        when (stringp e)
        collect e)
("I" "WANT" "THIS" "TEXT")
还包括:

CL-USER 17 > (defun skip-lines-until (stream stop-line)
               (loop for line = (read-line stream nil)
                     while (and line
                                (not (string= line stop-line)))))
SKIP-LINES-UNTIL

CL-USER 18 > (defun collect-lines-until (stream stop-line)
               (loop for line = (read-line stream nil)
                     while (and line (not (string= line stop-line)))
                     collect line))
COLLECT-LINES-UNTIL

CL-USER 19 > (let ((lines "hi
there
start
1
2
3
stop
more
here"))
               (with-input-from-string (stream lines)
                 (skip-lines-until stream "start")
                 (collect-lines-until stream "stop")))
("1" "2" "3")
还包括:

CL-USER 17 > (defun skip-lines-until (stream stop-line)
               (loop for line = (read-line stream nil)
                     while (and line
                                (not (string= line stop-line)))))
SKIP-LINES-UNTIL

CL-USER 18 > (defun collect-lines-until (stream stop-line)
               (loop for line = (read-line stream nil)
                     while (and line (not (string= line stop-line)))
                     collect line))
COLLECT-LINES-UNTIL

CL-USER 19 > (let ((lines "hi
there
start
1
2
3
stop
more
here"))
               (with-input-from-string (stream lines)
                 (skip-lines-until stream "start")
                 (collect-lines-until stream "stop")))
("1" "2" "3")

如果您想在一个地方完成所有工作,可以使用loop对状态机进行编码:

(with-open-file (in "/tmp/example")
  (loop
    for previous = nil then line
    for line = (read-line in nil nil)
    for start = (equal previous "start")
    for end = (equal line "end")
    for active = nil then (and (not end) (or active start))
    while line
    when active collect line))
下面是一个表,它列出了在一段时间内每个循环变量绑定的值,其中点表示可读性为零

|----------+-------+-------+-------+------+------|
| line     | hello | start | text  | text | end  |
|----------+-------+-------+-------+------+------|
| previous | .     | hello | start | text | text |
| start    | .     | .     | T     | .    | .    |
| end      | .     | .     | .     | .    | T    |
| active   | .     | .     | T     | T    | .    |
|----------+-------+-------+-------+------+------|

如果您想在一个地方完成所有工作,可以使用loop对状态机进行编码:

(with-open-file (in "/tmp/example")
  (loop
    for previous = nil then line
    for line = (read-line in nil nil)
    for start = (equal previous "start")
    for end = (equal line "end")
    for active = nil then (and (not end) (or active start))
    while line
    when active collect line))
下面是一个表,它列出了在一段时间内每个循环变量绑定的值,其中点表示可读性为零

|----------+-------+-------+-------+------+------|
| line     | hello | start | text  | text | end  |
|----------+-------+-------+-------+------+------|
| previous | .     | hello | start | text | text |
| start    | .     | .     | T     | .    | .    |
| end      | .     | .     | .     | .    | T    |
| active   | .     | .     | T     | T    | .    |
|----------+-------+-------+-------+------+------|

与其在Lisp中重新发明一小部分awk,不如使用awk进行初始过滤,然后使用Lisp程序消化其输出?我想,但这是我的第一个lisp项目,所以我想尽我所能来试驾它。与其在lisp中重新发明awk的一小部分,不如使用awk来进行初始过滤,然后使用lisp程序来消化它的输出,这不是更容易吗?@tfb我想了想,但这是我的第一个lisp项目,所以我想尽我所能来试驾它。这是一个有趣的方法来完成这一点。我想在我完全掌握这一点之前,我必须建立起我的知识循环。这是一个实现这一点的有趣方法。我想在我完全掌握这一点之前,我必须建立起我的知识循环。