Common Lisp で dircat

あるディレクトリ内の全ファイルを cat(猫)する必要があった.しかし cat(猫)でやろうとしたら引数が多すぎると文句を言われた.そこで Common Lisp で書いた.なお CL の知識は Land of Lisp を半分読んだくらいしかありません.

roswell とかいうのを使っていて,インストールすれば実行可能ファイルとして実行できる.

github.com

#!/bin/sh
#|-*- mode:lisp -*-|#
#|
exec ros -Q -- $0 "$@"
|#

;;;; cat recursively in specified directory

;; init forms
(progn
  (ros:ensure-asdf)
  #+quicklisp (ql:quickload '(:cl-fad :alexandria) :silent t)
  )

(defun write-bytes (result-type seq stm)
  (map result-type
       (lambda (x)
         (write-byte x stm))
       seq))

(defun mainproc (dirpath)
  (cl-fad:walk-directory
    dirpath
    (lambda (path)
      (write-bytes
        nil (alexandria:read-file-into-byte-vector path) *standard-output*))))

(defun print-usage ()
  (format t "Usage: ./dircat.ros DIRPATH~%"))

(defun error-exit (msg)
  (format t "~a~%~%" msg)
  (print-usage)
  1)

(defun main (&rest argv)
  (if (eql (length argv) 1)
    (let* ((arg (car argv))
           (dirpath (cl-fad:directory-exists-p arg)))
      (if dirpath
        (mainproc dirpath)
        (error-exit (format nil "~s is not a directory" arg))))
    (error-exit "Illegal number of arguments (Expected 1)")))

;;; vim: set ft=lisp lisp:

一見うまく動いているようなので,残業せずに済んだ.しかし,普通の cat(猫)と比べると遅い.にゃんでかな.

お会社にお言語オタクみたいな人がいなくて寂しい.