日常LISP (1) ファイル内の文字列置換 — #:g1

Posted 2010-12-21 14:34:00 GMT

とにかく普段からLISPを使っていこうという、有意義なのかどうか分からない試みの記録。
日々遭遇するちょっとした仕事をできる限りCommon Lispで処理し、その感想をつらつらとまとめます。
できそうではあったけれど、手間や環境が原因でシェルスクリプト等に逃げてしまったものは、メモしておいて次回の対策を練ってみます。

さて、今日は、sedでできそうな仕事をCLで処理しました。
以前、職場のブログに書いてしまったネタとかぶる気がしますが、まあ良しとします。

(defun run ()
  (let ((suf "_removeme_"))
    (iterate ((file (scan (directory "/tmp/foo/**/*.html"))))
      (let ((nfile (format nil "~A.~A.htm" file suf)))
        (with-< (in file)
          (with-> (out nfile)
            (sed "<!-- ここからですよ -->"
                 "<!-- ここまでですよ -->"
                 "置換する内容ですよ
2行目ですよ
3行目ですよ"
                 :in in
                 :out out)))
        (rename-file nfile file)))))
;;
(run)
作業内容は、
+ あるディレクトリ以下のHTMLファイル全部を開き
+ 「ここから〜ここまで」を「置換する内容ですよ」で置換
+ 置換した内容で上書き
という内容です。
実行は、SLIME上から実行します。

使っているライブラリは、
+ series(iterate、scan)
+ 俺関数
です。
俺関数ですが、
+WITH-<、WITH->はWITH-OPEN-FILEをちょっと加工したもので、入力と出力専用です。(WITH->はUnix風に上書き基本です。)
+SEDはsed風な動きをするだけで全然sedじゃないですが良いんです。
というところです。

おすすめポイントですが、細かいところは処理系依存のようですが、DIRECTORY(というかCLのパス名)は、**/*.htmlというzshのように再帰的に表記ができます。
これとENSURE-DIRECTORIES-EXISTを組み合せると結構便利だったりします。

気持ち的に負けてるなと感じるポイントは、パス周りを文字列として扱っているところですが、色々面倒なので割り切ってます。

comments powered by Disqus