読者です 読者をやめる 読者になる 読者になる

ローカルにあるはてダラのテキストからタグ検索してこれるツールをHaskellで作った

Haskell

Haskellやりたかっただけです。本当に(ry。

こういうファイルからタグが存在するファイルのタイトルと、ファイル名を出力する。

*1209837908*[test][Haskell]aaa
hoge

一つのファイルしか読み込むようにしてないけど、僕にはxargsがいるので大丈夫。こんな感じで実行。

ls /home/yasuhisa/.hatena/syou6162/diary/*.txt /home/yasuhisa/.hatena/syou6162/group/syou6162/*.txt | sort -r | 
xargs -n1 ./local_hatena_search Haskell

すると、こんな感じでタグ検索をすることができる。シンプルでなかなかよいと思う。

本文検索も付けようかと思ったが、それはgrepのお仕事なので、実装するのは取りやめた。これでファイル名に当りを付けたらlessとかやればおk。

ソース。コンパイルしないで実行してて「なんでこんなに遅いんだーーーー」とか思ってたが、コンパイルしたら実用的な速さになった。

import List
import Char
import System

search :: String -> String -> String
search search str = if (isTitle str)
                    then if foldl (||) False $ map (isPrefixOf $ "[" ++ search ++ "]" ) ( tails str)
                         then str
                         else ""
                    else ""

existSeachWord :: String -> String -> Bool
existSeachWord search str = if (isTitle str)
                    then if foldl (||) False $ map (isPrefixOf $ "[" ++ search ++ "]" ) ( tails str)
                         then True
                         else False
                    else False

-- titleの部分かを判定する関数
-- こういう書式かどうかのチェック「*1209837908*[Haskell]Haskellリハビリ」
isTitle :: String -> Bool
isTitle [] = False
isTitle title = foldl (&&) True $ map isDigit $ take 10 $ tail title

-- 空のリストを取り除く
removeEmpties :: [String] -> [String]
removeEmpties ls = filter (\x -> length x /= 0) ls

main = do args <- getArgs
          file <- readFile $ head $ tail $ args
          if foldl (||) False $ map (existSeachWord $ head $ args) (lines $ file)
            then do putStrLn $ head $ tail $ args
                    putStr $ unlines $ removeEmpties $ map (search $ head $ args) (lines $ file)
            else putStr ""

慣れないので、IO周りにやたら時間を取られた。あと、haskell-modeのif then elseのインデントがおかしい気がするんだけど、気のせいかな?

追記

思ったより使えそうなのでaliasに登録などした*1。.zshrcとかに書いておく。

alias H="ls /home/yasuhisa/.hatena/syou6162/diary/*.txt /home/yasuhisa/.hatena/syou6162/group/syou6162/*.txt | sort -r | xargs -n1 /home/yasuhisa/haskell/local_hatena_search"

だいたい目星がついたら、screenのcopy modeとかにして、lessで見ればよい。全部が見たければ、

H Perl | perl -ne 'print unless /^\*/' | xargs cat | less

という風にすればよい。あ、でもこれだとその日の関係ないエントリも上がってくるのがうざいのが欠点。

*1:日本語とかも普通に通って逆にびびる