eml形式の(要は1メール1ファイルの)メールテキストがいっぱいあってこれを、CSVのレコードにして、一覧にしたいという。
よくわからないが、適当なツールをさがしてみたが、いいのがない。
捜すのが下手なのかもしれない。
しかたがないので、適当に書いてみた。
ひょっとしたら、date は 日付と時間にわけたほうがよかったのかもしれない。
(ql:quickload :cl-ppcre) (ql:quickload :csv-parser) (ql:quickload :cl-fad) (defvar *max-message-body-limit* 50) ;; max line for message body ;;;; #| ; if it works on windows (setf ccl:*default-external-format* (ccl:make-external-format :character-encoding :cp932 :line-termination :dos)) ; or other (setf ccl:*default-external-format* (ccl:make-external-format :character-encoding :utf8 :line-termination :unix)) |# (defun read-txt-mail (file) (let ((from nil) (subject nil) (date nil) (message-body "") (message-body-count nil)) (with-open-file (in file :direction :input) (loop for line = (read-line in nil nil) while line do (progn (setf from (get-var from line "^From:" ": ")) (setf subject (get-var subject line "^Subject:" ": ")) (setf date (get-var date line "^Date:" ": ")) (if message-body-count (when (< message-body-count *max-message-body-limit*) (incf message-body-count) (setf message-body (format nil "~a~%~a" message-body line))) (when (cl-ppcre:scan "^\\s*$" line) (setf message-body-count 0)))))) (list subject from date message-body))) (defun get-var (var line regex delimit) (if var var (if (cl-ppcre:scan regex line) (nth 1 (cl-ppcre:split delimit line)) nil))) (defun read-dir (path) (let ((lst nil)) (cl-fad:walk-directory (cl-fad:pathname-as-directory path) (lambda (x) (when (string-equal (pathname-type x) "txt") (push (read-txt-mail (namestring x)) lst)))) (reverse lst))) (defun lst-lst-csv (lst file) (with-open-file (out file :direction :output) (dolist (ls lst) (csv-parser:write-csv-line out ls) ))) (defun main () (if (<= (length ccl:*command-line-argument-list*) 1) (format t "this program require 2 args for dir name (input) and csv file name (output) ") (lst-lst-csv (read-dir (first ccl:*command-line-argument-list*)) (second ccl:*command-line-argument-list*))))