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:日本語とかも普通に通って逆にびびる