我有每行一个句子的文本文件。 我想lemmatize使用中的hunspell(-s选项)每行中的世界。 因为我想单独有各行的引理,那就没有意义提交整个文本文件与hunspell。 我确实需要陆续发送一行,并为每个行中的hunspell输出。
从之后的答案如何处理输入和输出流中钢银行Common Lisp的? ,我能够陆续发送整个文本文件中的hunspell一个线,但我没能捕捉到的hunspell的输出的每一行。 如何与过程发送线和读取输出之前发送另一个线互动?
我当前的代码读取整个文本文件是
(defun parse-spell-sb (file-in)
(with-open-file (in file-in)
(let ((p (sb-ext:run-program "/opt/local/bin/hunspell" (list "-i" "UTF-8" "-s" "-d" "pt_BR")
:input in :output :stream :wait nil)))
(when p
(unwind-protect
(with-open-stream (o (process-output p))
(loop
:for line := (read-line o nil nil)
:while line
:collect line))
(process-close p))))))
再次,这个代码给我的hunspell的整个文本文件的输出。 我想单独具有的hunspell的每个输入线的输出。
任何的想法?
我想你有你想要运行的程序的缓冲问题。 例如:
(defun program-stream (program &optional args)
(let ((process (sb-ext:run-program program args
:input :stream
:output :stream
:wait nil
:search t)))
(when process
(make-two-way-stream (sb-ext:process-output process)
(sb-ext:process-input process)))))
现在,我的系统上,这将与cat
:
CL-USER> (defparameter *stream* (program-stream "cat"))
*STREAM*
CL-USER> (format *stream* "foo bar baz~%")
NIL
CL-USER> (finish-output *stream*) ; will hang without this
NIL
CL-USER> (read-line *stream*)
"foo bar baz"
NIL
CL-USER> (close *stream*)
T
注意finish-output
-如果没有这个,读将挂起。 (还有force-output
。)
Python的交互模式下都可以工作,太:
CL-USER> (defparameter *stream* (program-stream "python" '("-i")))
*STREAM*
CL-USER> (loop while (read-char-no-hang *stream*)) ; skip startup message
NIL
CL-USER> (format *stream* "1+2~%")
NIL
CL-USER> (finish-output *stream*)
NIL
CL-USER> (read-line *stream*)
"3"
NIL
CL-USER> (close *stream*)
T
但是,如果你试试这个没有-i
选项(或类似类似的选项-u
),你可能是出于运气,因为缓冲回事。 例如,我的系统上,从阅读tr
将挂起:
CL-USER> (defparameter *stream* (program-stream "tr" '("a-z" "A-Z")))
*STREAM*
CL-USER> (format *stream* "foo bar baz~%")
NIL
CL-USER> (finish-output *stream*)
NIL
CL-USER> (read-line *stream*) ; hangs
; Evaluation aborted on NIL.
CL-USER> (read-char-no-hang *stream*)
NIL
CL-USER> (close *stream*)
T
由于tr
不提供开关关闭缓冲,我们将包裹带PTY包装的调用(在这种情况下, unbuffer
的期待):
CL-USER> (defparameter *stream* (program-stream "unbuffer"
'("-p" "tr" "a-z" "A-Z")))
*STREAM*
CL-USER> (format *stream* "foo bar baz~%")
NIL
CL-USER> (finish-output *stream*)
NIL
CL-USER> (read-line *stream*)
"FOO BAR BAZ
"
NIL
CL-USER> (close *stream*)
T
所以,长话短说:尝试使用finish-output
流上的读数。 如果还是不行,请检查命令行选项防止缓冲。 如果仍然无法正常工作,你可以尝试在某种PTY-包装的包裹PROGRAMM。