在 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")
                " "))))