在 Guile 或其他 Scheme 中,如何将输入文件或标准输入中的第 n 个空白分隔字段打印到标准输出?
In Guile or other Scheme, how to print to standard output the nth blank delimited field of lines from the input file or standard input?
如果 Guile 不是这种用法的最佳方案,那么我应该看哪一个?我基本上是在寻找 awk '{print $N}'
的 Guile 等价物。如果 Scheme 不能做到这一点,那么我想知道为什么不能。
在我的博客中,我 an essay 提供了一组函数,可以轻松处理带分隔符的文本文件。
Guile 在 2.0 和 2.2 之间稍微改变了它的 I/O,所以它使用 r6rs I/O 两者(希望)工作相同,但我没有用 2.2 测试过。
这可以进一步优化。
#!/usr/bin/guile \
-e start -s
!#
(use-modules (rnrs io ports))
;;; Reads one line from current-input-port and prints the field indicated by
;;; field-num. If the line does not have enough fields, it prints a newline.
;;; Returns the field, an empty string, or #f if end of file is reached.
(define (get-field field-num)
(let ((line (get-line (current-input-port))))
(if (eof-object? line)
#f
(let ((fields (string-tokenize line)))
(if (< field-num (length fields))
(let ((field (list-ref fields field-num)))
(put-string (current-output-port)
(string-append field "\n"))
field)
(and (put-string (current-output-port) "\n")
""))))))
;;; Repeat get-field until until end of file is reached
(define (get-all-fields field-num)
(if (get-field field-num)
(get-all-fields field-num)
#f))
(define (start args)
(if (and (> (length args) 1)
(integer? (string->number (list-ref args 1))))
(get-all-fields (1- (string->number (list-ref args 1))))
(display (string-join
`("Usage:" ,(list-ref args 0) "<field-number>\n")
" "))))
如果 Guile 不是这种用法的最佳方案,那么我应该看哪一个?我基本上是在寻找 awk '{print $N}'
的 Guile 等价物。如果 Scheme 不能做到这一点,那么我想知道为什么不能。
在我的博客中,我 an essay 提供了一组函数,可以轻松处理带分隔符的文本文件。
Guile 在 2.0 和 2.2 之间稍微改变了它的 I/O,所以它使用 r6rs I/O 两者(希望)工作相同,但我没有用 2.2 测试过。
这可以进一步优化。
#!/usr/bin/guile \
-e start -s
!#
(use-modules (rnrs io ports))
;;; Reads one line from current-input-port and prints the field indicated by
;;; field-num. If the line does not have enough fields, it prints a newline.
;;; Returns the field, an empty string, or #f if end of file is reached.
(define (get-field field-num)
(let ((line (get-line (current-input-port))))
(if (eof-object? line)
#f
(let ((fields (string-tokenize line)))
(if (< field-num (length fields))
(let ((field (list-ref fields field-num)))
(put-string (current-output-port)
(string-append field "\n"))
field)
(and (put-string (current-output-port) "\n")
""))))))
;;; Repeat get-field until until end of file is reached
(define (get-all-fields field-num)
(if (get-field field-num)
(get-all-fields field-num)
#f))
(define (start args)
(if (and (> (length args) 1)
(integer? (string->number (list-ref args 1))))
(get-all-fields (1- (string->number (list-ref args 1))))
(display (string-join
`("Usage:" ,(list-ref args 0) "<field-number>\n")
" "))))